Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JWT bearer tokens w/ ASP.NET Identity 3

Based on the great example by Shaun Luttin at https://stackoverflow.com/a/30857524 I was able to use that code to generate and consume bearer tokens. Minor changes were to get the latest packages:

"dependencies": {
  "Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final",
  "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4"
}

Although the code is a great start, it's not a complete solution that integrates w/ ASP.NET Identity completely. I modified AuthorizationProvider class as follows:

public override Task GrantResourceOwnerCredentials(
    GrantResourceOwnerCredentialsContext context)
{
    var user = _userManager.FindByNameAsync(context.UserName).Result;
    if (user == null)
    {
        context.Rejected("The user name or password is incorrect.");
    }
    else
    {
        var signInManager = context.HttpContext.RequestServices
            .GetRequiredService<SignInManager<ApplicationUser>>();

        if (signInManager.CanSignInAsync(user).Result &&
            _userManager.CheckPasswordAsync(user, context.Password).Result)
        {
            var principal = signInManager.CreateUserPrincipalAsync(user).Result;

            //To avoid leaking confidential data, AspNet.Security.OpenIdConnect.Server
            //refuses to serialize the claims that don't explicitly specify a destination.
            foreach (var claim in principal.Claims)
                claim.WithDestination("token id_token");

            context.Validated(principal);
        }
        else
            context.Rejected("The user name or password is incorrect.");
    }

    return Task.FromResult(0);
}

I'm using CreateUserPrincipalAsync to create the ClaimsPrincipal for the Validated method. Is there a better way to integrate w/ ASP.NET Identity?

like image 732
Mark G Avatar asked Oct 30 '22 14:10

Mark G


1 Answers

Your implementation looks fine, minor 3 remarks:

  • You should use async/await to avoid the .Result blocking calls.
  • You should consider implementing brute-force countermeasures, as required by the OAuth2 specifications: https://www.rfc-editor.org/rfc/rfc6749#section-4.3.2. It's something you can easily do with Identity 3 as it offers native support for "lockout".
  • You must keep in mind that this implementation will result in serializing all the claims (even custom ones) associated with the user, which might include confidential data.

The last two points are mitigated in OpenIddict (a whole new experimental OIDC server that uses AspNet.Security.OpenIdConnect.Server internally), so don't hesitate to take a look at its default implementation: https://github.com/openiddict/core/blob/dev/src/OpenIddict.Core/OpenIddictProvider.cs#L353.

like image 103
Kévin Chalet Avatar answered Nov 17 '22 09:11

Kévin Chalet