2017-06-28 2 views
0

Ich habe eine. Net Core API API und SPA-Client in React JS. Ich möchte Benutzern erlauben, sich mit ihren in Azure AD registrierten E-Mails vom Client aus anzumelden und meine Web-API mit JWT Token zu sichern. Ich habe versucht, Token mit einem einfachen hartcodierten Benutzernamen und einem Passwort zu generieren, aber ich habe keine Ahnung, wie ich Nutzer von Azure AD holen und JWT-Token generieren kann.So erhalten Sie Benutzer von Azure AD beim Sichern asp.net Core Web API mit JWT-Token

Hier ist mein JWTController:

[Route("api/[controller]")] 
public class JwtController : Controller 
{ 
    private readonly JwtIssuerOptions _jwtOptions; 
    private readonly ILogger _logger; 
    private readonly JsonSerializerSettings _serializerSettings; 

    public JwtController(IOptions<JwtIssuerOptions> jwtOptions, ILoggerFactory loggerFactory) 
    { 
     _jwtOptions = jwtOptions.Value; 
     ThrowIfInvalidOptions(_jwtOptions); 

     _logger = loggerFactory.CreateLogger<JwtController>(); 

     _serializerSettings = new JsonSerializerSettings 
     { 
      Formatting = Formatting.Indented 
     }; 
    } 

    [HttpPost] 
    [AllowAnonymous] 
    public async Task<IActionResult> Get([FromForm] string Username, string Password) 
    { 
     var applicationUser = new ApplicationUser(); 
     applicationUser.UserName = Username; 
     applicationUser.Password = Password; 
     var identity = await GetClaimsIdentity(applicationUser); 
     if (identity == null) 
     { 
      _logger.LogInformation($"Invalid username({applicationUser.UserName}) or password ({applicationUser.Password})"); 
      return BadRequest("Invalid credentials"); 
     } 

     var claims = new[] 
     { 
      new Claim(JwtRegisteredClaimNames.Sub, applicationUser.UserName), 
      new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()), 
      new Claim(JwtRegisteredClaimNames.Iat, 
       ToUnixExpochDate(_jwtOptions.IssuedAt).ToString(), 
       ClaimValueTypes.Integer64), 
      identity.FindFirst("Disney") 
     }; 

     //Create the JWT security token and encode it. 
     var jwt = new JwtSecurityToken(
      issuer: _jwtOptions.Issuer, 
      audience: _jwtOptions.Audience, 
      claims:claims, 
      notBefore:_jwtOptions.NotBefore, 
      expires:_jwtOptions.Expiration, 
      signingCredentials:_jwtOptions.SigningCredentials); 

     var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); 

     //Serialize and return the response. 
     var response = new 
     { 
      access_token = encodedJwt, 
      expires_in = (int)_jwtOptions.ValidFor.TotalSeconds 
     }; 

     var json = JsonConvert.SerializeObject(response, _serializerSettings); 
     return new OkObjectResult(json); 
    } 

    private static void ThrowIfInvalidOptions(JwtIssuerOptions options) 
    { 
     if (options == null) throw new ArgumentNullException(nameof(options)); 

     if (options.ValidFor <= TimeSpan.Zero) 
     { 
      throw new ArgumentException("Must be a non-zero TimeSpan.", nameof(JwtIssuerOptions.ValidFor)); 
     } 

     if (options.SigningCredentials == null) 
     { 
      throw new ArgumentNullException(nameof(JwtIssuerOptions.SigningCredentials)); 
     } 

     if (options.JtiGenerator == null) 
     { 
      throw new ArgumentNullException(nameof(JwtIssuerOptions.JtiGenerator)); 
     } 
    } 

    private static long ToUnixExpochDate(DateTime date) 
     => (long)Math.Round((date.ToUniversalTime() - 
      new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)) 
      .TotalSeconds); 

    private Task<ClaimsIdentity> GetClaimsIdentity(ApplicationUser user) 
    { 
     if (user.UserName == "mickey" && user.Password == "mouse") 
     { 
      return Task.FromResult(new ClaimsIdentity(
       new GenericIdentity(user.UserName, "Token"), 
       new[] 
       { 
        new Claim("Disney", "mickey") 
       })); 
     } 

     if (user.UserName == "notmickey" && user.Password == "mouse") 
     { 
      return Task.FromResult(new ClaimsIdentity(
       new GenericIdentity(user.UserName, "Token"), 
       new Claim[] { })); 
     } 

     return Task.FromResult<ClaimsIdentity>(null); 
    } 
} 

jemand eine Idee, wie dies zu implementieren?

Antwort

1

Ich denke, Sie haben es ein bisschen zurück.

Ihre Reaktion Client sollte eine Umleitung zu Azure AD-Anmeldeseite tun, und dann die JWT von Azure AD Holen Ihre API aufrufen. Dann muss Ihre API lediglich die eingehenden Token validieren und eine Benutzeridentität für die Anfrage erstellen. Dafür gibt es fertige Komponenten in ASP.NET Core.

Ein Beispiel für die Verwendung Adal.js mit React: https://blog.mastykarz.nl/building-office-365-web-applications-react/

Beispiel Azure AD v2 Verwendung in ASP.NET MVC Core-API: https://contos.io/protecting-a-net-core-api-with-azure-active-directory-59bbcd5b3429

+0

ich nicht bekommen es. Wie werden die JWT-Token von AzureAD mit einer einfachen Umleitung auf der Client-Seite generiert? –

+0

Sehen Sie sich das Ablaufdiagramm hier an, um eine Vorstellung davon zu bekommen, wie es funktioniert: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-scenarios#single-page-application- Spa. Wenn Ihr API- und SPA-Front-End in Azure AD die gleiche App ist, können Sie wie dort erwähnt vorgehen und einfach das ID-Token senden. Andernfalls können Sie Adal.js verwenden, um zusätzliche Zugriffstoken für andere APIs abzurufen. – juunas

+0

Es gibt auch eine Beispielanwendung, die Angular verwendet: https://github.com/Azure-Samples/active-directory-angularjs-singlepageapp – juunas

Verwandte Themen