I am using an iDP that provides the username in the 'sub' claim which inside abp does not mark the CurrentUser.IsAuthenticated
to true and the id
for the user is also null because it is not a GUID.
From the documentation I found that you can inherit AbpUserClaimsPrincipalFactory
and add your custom claims. I thought I could override the NameIdentifier claim and pull the mapped user from the database and use that GUID custom UserClaimsPrincipalFactory
never gets called.
Below is my code:
I have tried the below implementation but CreateAsync
never gets called.
public class BaselineUserClaimsPrincipalFactory : AbpUserClaimsPrincipalFactory
{
private readonly ICoreApiService _coreApiService;
public BaselineUserClaimsPrincipalFactory(
UserManager<IdentityUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> options,
ICurrentPrincipalAccessor currentPrincipalAccessor,
IAbpClaimsPrincipalFactory abpClaimsPrincipalFactory,
ICoreApiService coreApiService)
: base(
userManager,
roleManager,
options,
currentPrincipalAccessor,
abpClaimsPrincipalFactory)
{
_coreApiService = coreApiService;
}
[UnitOfWork]
public async override Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
{
var principal = await base.CreateAsync(user);
var identity = principal.Identities.First();
if (identity != null)
{
.
.
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user_guid));
}
return principal;
}
}
Inside BaselineHttpApiHostModule
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IdentityBuilder>(builder => builder.AddClaimsPrincipalFactory<BaselineUserClaimsPrincipalFactory>());
}
using IdentityUser = Volo.Abp.Identity.IdentityUser;
public class ServiceClaimTransformation : IClaimsTransformation
{
private readonly UserManager<IdentityUser> _userManager;
public ServiceClaimTransformation(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var identity = principal.Identities.FirstOrDefault();
if (identity != null)
{
var usernameClaim = identity.Claims.FirstOrDefault(t => t.Type == ClaimTypes.NameIdentifier);
if (usernameClaim != null)
{
var dbUser = await _userManager.FindByNameAsync(usernameClaim.Value);
if (dbUser != null)
{
identity.RemoveClaim(usernameClaim);
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, dbUser.Id.ToString()));
}
}
}
return principal;
}
}
Above is what I ended up doing. This will find the user within the db by username and add their user id to the claims. Below is how you would register in your startup.
context.Services.AddTransient<IClaimsTransformation, ServiceClaimTransformation>();