Asp.Net Core 3.0
I am using the ASP.NET Core web application with Angular and Authentication
(Individual User Accounts) template (from Visual Studio 2019).
My intention is to add some Custom Claims in the generated JWT
and use them in browser.
In order to do that, I have extended the UserClaimsPrincipalFactory
public class MyCustomClaimsInjector : UserClaimsPrincipalFactory<ApplicationUser>
{
public MyCustomClaimsFactory(UserManager<ApplicationUser> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor)
{
}
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
{
var id = await base.GenerateClaimsAsync(user);
id.AddClaim(new Claim("my_claim1", "AdditionalClaim1"));
id.AddClaim(new Claim("my_claim2", "AdditionalClaim2"));
return id;
}
}
As well, I have registered the extension in the Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddClaimsPrincipalFactory<MyCustomClaimsFactory>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
During Sign In phase, started from the SPA client, the debugger passes through MyCustomClaimsFactory
and adds the claims to the ClaimsIdentity
in the GenerateClaimsAsync
method.
But, I find strange why the JWT received in browser does not contain the Claims added by the MyCustomClaimsFactory
.
Is my expectation to see the Custom Claim in the JWT in browser OK ?
Can anyone suggest the direction to dig in... Why the claims isn't present in the JWT ?
Decoded JWT is:
The SPA app:
Will share my results. Hope that will help anyone else.
I have implemented IProfileService
and piped the .AddProfileService<ProfileService>()
implementation in ConfigureServices
.
public class ProfileService : IProfileService
{
protected UserManager<ApplicationUser> _userManager;
public ProfileService(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var user = await _userManager.GetUserAsync(context.Subject);
var claims = new List<Claim>
{
new Claim("my_FirstName", "user_FirstName"),
new Claim("my_LastName", "user_LastName")
};
context.IssuedClaims.AddRange(claims);
}
public async Task IsActiveAsync(IsActiveContext context)
{
var user = await _userManager.GetUserAsync(context.Subject);
context.IsActive = (user != null);
}
}
the Startup.cs file
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>()
.AddProfileService<ProfileService>();
With that, now the JWT contains my custom claims.
I am not sure why the override for UserClaimsPrincipalFactory
was not able to solve that.
Will try to study deeper those areas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With