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
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
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>>();