Hi,
I did override the CreateAsync method of the UserClaimsPrincipalFactory and added one more claim called "Application_UserCustomerId".
Now i want to update it with a trigger from the ui: ui sends me a new customerId and i want to set the claims value with this new value.
I have my own app session class in which i have a getter and setter for the CustomerId as follows:
public int? CustomerId
{
get
{
var customerIdClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == "Application_UserCustomerId");
if (customerIdClaim == null || string.IsNullOrEmpty(customerIdClaim.Value))
{
return null;
}
return Convert.ToInt32(customerIdClaim.Value);
}
set
{
var identity = (ClaimsIdentity)PrincipalAccessor.Principal.Identity;
var existingClaim = identity.FindFirst("Application_UserCustomerId");
if (existingClaim != null)
{
identity.RemoveClaim(existingClaim);
}
if (value.HasValue)
{
identity.AddClaim(new Claim("Application_UserCustomerId", value.Value.ToString()));
}
}
}
for some reason the setter doesnt seem to work. no matter what i set the customerId, it always stays at its initial value.
am i doing something wrong?
i apologize if this isnt a direct abp question but i still wanted to ask here since i use the abp core structure to manage claims and such.
thank you
5 Answer(s)
-
0
Hi @uenlkr4e
After updating the user's claims, do you log the user in and out for the relevant user? Here, we think that the claim information kept by the token is not updated? Since the request made depends on the user and the claims of this user are kept by the Principal, an update must be made here as well. When logging in again for the user, do not forget to set the relevant claims to the user. The sample code below will help you.
public async Task UpdateCurrentUserClaimAsync(string claimType, string newClaimValue) { var user = await _userManager.GetUserAsync(AbpSession.ToUserIdentifier()); if (user == null) { throw new Exception("User not found."); } var existingClaims = await _userManager.GetClaimsAsync(user); var existingClaim = existingClaims.FirstOrDefault(c => c.Type == claimType); if (existingClaim != null) { await _userManager.RemoveClaimAsync(user, existingClaim); } await _userManager.AddClaimAsync(user, new Claim(claimType, newClaimValue)); await _signInManager.RefreshSignInAsync(user); }
-
0
Hi @oguzhanagir,
thank you for the answer.
I think i am doing something wrong. maybe i should draw you a bigger picture.user has CustomerId property in User table, so when a user logs in i create a claim called users_customer_id and set this value(by overriding CreateAsync method of UserClaimsPrincipalFactory).
Application uses this value just like a session variable ( i created my own app session class to reach this value).but now user will be allowed to change his customerId from the frontend, so whatever value is sent, i want to replace the users_customer_id claim value with this new one.
i tried your suggestion but it doesnt seem to work for me.
maybe you could have a better approach depending on my requirements above.
i really appreciate the help you are providing.
thanks -
0
Hi @uenlkr4e
Have you tried updating the
token
information? Claims created specifically for the user are kept in the token. After updating the Claim, you also need to renew thetoken
. -
0
Hi,
isntawait _signInManager.RefreshSignInAsync(user);
also refreshing the token?
-
0
Hi @uenlkr4e
Since we are using the JWT mechanism here, it is necessary to create a token manually. You need to create RefreshToken and AccessToken information using Claim's updated user information and identity information and resend the token to the client.