2

I am using Visual Studio 2015 Enterprise and ASP.NET vNext Beta8 to build an endpoint that both issues and consumes JWT tokens as described in detail here.

I am at the phase in my project where I want to allow the JWT bearer authentication to proceed as discussed in the article mentioned above, but once the token has been authenticated I want to:

  • Step in after successful JWT authentication and inspect its various claims.
  • Hydrate a scoped instance of my own principal object (say IContosoPrincipal) based on what I find in the token.
  • Ensure that the backing concrete for IContosoPrincipal is scoped to the current request.
  • Dependency inject IContosoPrincipal later into one of my token-guarded controllers.

I'm sure this will involve a scoped IContosoPrincipal object and I can likely figure that part out, but I'm not sure how to intercept JWT authentication after the token is successfully authenticated but before controller/action invocation takes place.

Any advice on how to approach this would be much appreciated.

Community
  • 1
  • 1
42vogons
  • 683
  • 7
  • 19

1 Answers1

3

Custom principals/identities are not (and won't be) officially supported in ASP.NET 5. You can find more information on this topic: https://github.com/aspnet/Security/issues/323.

Instead, you're strongly encouraged to store the data you need as individual claims, and provide extension methods around ClaimsIdentity/ClaimsPrincipal when needed (e.g if you need to format the claim value).

FWIW, this pattern is heavily used by ASP.NET Identity 3 itself, that comes with built-in extensions (like GetUserName or GetUserId) that you can use in your own code:

/// <summary>
/// Returns the User ID claim value if present otherwise returns null.
/// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal"/> instance this method extends.</param>
/// <returns>The User ID claim value, or null if the claim is not present.</returns>
/// <remarks>The User ID claim is identified by <see cref="ClaimTypes.NameIdentifier"/>.</remarks>
public static string GetUserId(this ClaimsPrincipal principal)
{
    if (principal == null)
    {
        throw new ArgumentNullException(nameof(principal));
    }
    return principal.FindFirstValue(ClaimTypes.NameIdentifier);
}

https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNet.Identity/PrincipalExtensions.cs

Kévin Chalet
  • 39,509
  • 7
  • 121
  • 131
  • thanks for this very informative and thorough answer. I would be lying if I said I wasn't disappointed though ; ) So allow me to ask this question differently - I want to dependency inject *something* into my controller that knows the ID of the user ID in my token (actually I have an aspect that is doing this but it's still DI). In vNext what is the accepted method for doing this. I noodled around in the AspNet.Identity source but their builder extensions immediately start doing things with cookies so not sure if this is barking up the wrong repo. – 42vogons Nov 04 '15 at 21:09
  • For that, directly retrieving the principal from the HTTP request (via `HttpContext`) is recommended. When your component doesn't have a direct access to the HTTP context, you can inject `IHttpContextAccessor` as a dependency and access the principal via `IHttpContextAccessor.HttpContext.User`. – Kévin Chalet Nov 04 '15 at 21:21
  • just a note that, as of today, PrincipalExtensions url is broken. Not sure if [this AspNetCore](https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNetCore.Identity/PrincipalExtensions.cs) is the actual one, as the content is different – superjos Jul 26 '16 at 16:59
  • it seems like they turned to a more generalized helper – superjos Jul 26 '16 at 17:10
  • @superjos FYI: these extensions have been replaced by instance methods on `UserManager` and `SignManager` (http://stackoverflow.com/questions/35693239/asp-net-mvc-core-equivalent-of-user-issignedin/35699374#35699374). – Kévin Chalet Jul 26 '16 at 17:12