Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Claims transformation support missing in ASP.NET Core 2.0

I am using JWT Bearer auth in my new asp.net core 2.0 api app and want to add some extra claims to the current identity. This extra info is located in another api which need to be queried. My understanding is that claims transformation would be the proper place to do this. In .net core 1.1 you have the IClaimsTransformer interface in Microsoft.AspNetCore.Authentication nuget package, but I cannot install this one in my .net core 2.0 app. Is there a alternative way to transform claims in asp.net core 2.0 and is this the correct approach for my use case?

like image 296
terjetyl Avatar asked Aug 16 '17 09:08

terjetyl


2 Answers

IClaimsTransformer has been renamed to IClaimsTransformation in ASP.NET Core 2.0.

Claims Transformation Simpler, new IClaimsTransformation service with a single method: Task TransformAsync(ClaimsPrincipal principal) We call this on any successful AuthenticateAsync call.

services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();

private class ClaimsTransformer : IClaimsTransformation {
    // Can consume services from DI as needed, including scoped DbContexts
    public ClaimsTransformer(IHttpContextAccessor httpAccessor) { }
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal p) {
        p.AddIdentity(new ClaimsIdentity());
        return Task.FromResult(p);
    }
}

See https://github.com/aspnet/Security/issues/1310

like image 72
Canada Wan Avatar answered Oct 20 '22 01:10

Canada Wan


There is another method for transforming claims in ASP.NET Core 2.0 which also gives you access to the UserStore so you can retrieve data on the user and add that information as claims. Basically you write an implementation of the interface IUserClaimsPrincipalFactory and configure using it adding your custom implementation as a service in the ConfigureServices method in Startup.cs. The main changes in Core 2.0 from Core 1.x is that Identity relies on dependency injection of services instead of using middleware in the identity pipeline. There is a complete example on creating a custom IUserClaimsPrincipalFactory and how to use it for authorization in this blog post.

Here is an example of creating a custom claims factory that sets a claim for whether the user is an administrator or not.

    public class MyClaimsPrincipalFactory<TUser>: UserClaimsPrincipalFactory<TUser> where TUser : ApplicationUser
    {
        public MyClaimsPrincipalFactory(
        UserManager<TUser> userManager,
        IOptions<IdentityOptions> optionsAccessor) : base(userManager, 
         optionsAccessor)
       {

        }

    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(TUser user)
    {
        var id = await base.GenerateClaimsAsync(user);
        id.AddClaim(new Claim(MyClaimTypes.IsAdmin, user.IsAdministrator.ToString().ToLower()));
        return id;
    }
  }

And here is how you inject the custom factory.

services.AddTransient<IUserClaimsPrincipalFactory<ApplicationUser>, MyClaimsPrincipalFactory<ApplicationUser>>();
like image 37
Kevin Junghans Avatar answered Oct 19 '22 23:10

Kevin Junghans