Open Closed

How to remove the unused claims in access token? #3858


User avatar
0
nhontran created
  • ABP Framework version: v5.2.2
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes / no
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

Hi, I want to remove the "unique_name" and "preferred_username" claims in the access token but could not figure out how to do it, I have tried to remove all the claims in Api Resources, but these claims still exist.

any idea how to remove it?


6 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can add a new IAbpClaimsPrincipalContributor to remove some claims from context.ClaimsPrincipal.Identities.FirstOrDefault()

    https://docs.abp.io/en/abp/latest/Authorization#claims-principal-factory

  • User Avatar
    0
    nhontran created

    Hi @maliming, I have tried and it does not work, the claim is not returned in the claim list:

    public class CustomClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
        {
            public Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
            {
                var identity = context.ClaimsPrincipal.Identities.FirstOrDefault();
                if (identity != null)
                {
                    // these 2 claims not found
                    var uniqueNameClaim = identity.FindFirst("unique_name");
                    var preferredUserNameClaim = identity.FindFirst("preferred_username");
                    identity.TryRemoveClaim(uniqueNameClaim);
                    identity.TryRemoveClaim(preferredUserNameClaim);
                }
                return Task.CompletedTask;
            }
        }
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

  • User Avatar
    0
    nhontran created

    Hi @maliming, which version did you check? it does not work with version 5.2.2.

    Could you check and let me know? Thank you.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    it does not work with version 5.2.2.

    Please create a 5.2.2 project and reproduce the problem then share it with me. Thanks

    limimg.ma@volosoft.com

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
    context.Services.Replace(ServiceDescriptor.Transient<IUserClaimsPrincipalFactory<IdentityUser>, MyUserClaimsFactory<IdentityUser>>());
    }
    
    using System;
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using System.Security.Claims;
    using System.Security.Principal;
    using System.Threading.Tasks;
    using IdentityModel;
    using Microsoft.AspNetCore.Identity;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Security.Claims;
    using IdentityUser = Volo.Abp.Identity.IdentityUser;
    
    
    namespace AbpApplicationTemplate;
    
    public class MyUserClaimsFactory<TUser> : IUserClaimsPrincipalFactory<TUser>
        where TUser : class
    {
        private readonly IObjectAccessor<IUserClaimsPrincipalFactory<TUser>> _inner;
        private readonly UserManager<TUser> _userManager;
        private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
        private readonly IAbpClaimsPrincipalFactory _abpClaimsPrincipalFactory;
    
        public MyUserClaimsFactory(IObjectAccessor<IUserClaimsPrincipalFactory<TUser>> inner,
            UserManager<TUser> userManager, ICurrentPrincipalAccessor currentPrincipalAccessor, IAbpClaimsPrincipalFactory abpClaimsPrincipalFactory)
        {
            _inner = inner;
            _userManager = userManager;
            _currentPrincipalAccessor = currentPrincipalAccessor;
            _abpClaimsPrincipalFactory = abpClaimsPrincipalFactory;
        }
    
        public async Task<ClaimsPrincipal> CreateAsync(TUser user)
        {
            var principal = await _inner.Value.CreateAsync(user);
            var identity = principal.Identities.First();
    
            if (!identity.HasClaim(x => x.Type == JwtClaimTypes.Subject))
            {
                var sub = await _userManager.GetUserIdAsync(user);
                identity.AddIfNotContains(new Claim(JwtClaimTypes.Subject, sub));
            }
    
            var username = await _userManager.GetUserNameAsync(user);
            var usernameClaim = identity.FindFirst(claim =>
                claim.Type == _userManager.Options.ClaimsIdentity.UserNameClaimType && claim.Value == username);
            if (usernameClaim != null)
            {
                identity.RemoveClaim(usernameClaim);
                identity.AddIfNotContains(new Claim(JwtClaimTypes.PreferredUserName, username));
    
                //https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/1627
                //https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/05e02b5e0383be40e45c667c12f6667d38e33fcc/src/System.IdentityModel.Tokens.Jwt/ClaimTypeMapping.cs#L52
                identity.AddIfNotContains(new Claim(JwtRegisteredClaimNames.UniqueName, username));
            }
    
            if (!identity.HasClaim(x => x.Type == JwtClaimTypes.Name))
            {
                identity.AddIfNotContains(new Claim(JwtClaimTypes.Name, username));
            }
    
            if (_userManager.SupportsUserEmail)
            {
                var email = await _userManager.GetEmailAsync(user);
                if (!string.IsNullOrWhiteSpace(email))
                {
                    identity.AddIfNotContains(new Claim(JwtClaimTypes.Email, email));
                    identity.AddIfNotContains(new Claim(JwtClaimTypes.EmailVerified,
                        await _userManager.IsEmailConfirmedAsync(user) ? "true" : "false", ClaimValueTypes.Boolean));
                }
            }
    
            if (_userManager.SupportsUserPhoneNumber)
            {
                var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
                if (!string.IsNullOrWhiteSpace(phoneNumber))
                {
                    identity.AddIfNotContains(new Claim(JwtClaimTypes.PhoneNumber, phoneNumber));
                    identity.AddIfNotContains(new Claim(JwtClaimTypes.PhoneNumberVerified,
                        await _userManager.IsPhoneNumberConfirmedAsync(user) ? "true" : "false",
                        ClaimValueTypes.Boolean));
                }
            }
    
            if (user is IdentityUser identityUser)
            {
                if (!identityUser.Name.IsNullOrEmpty())
                {
                    identity.AddIfNotContains(new Claim(JwtClaimTypes.GivenName, identityUser.Name));
                }
    
                if (!identityUser.Surname.IsNullOrEmpty())
                {
                    identity.AddIfNotContains(new Claim(JwtClaimTypes.FamilyName, identityUser.Surname));
                }
            }
    
            using (_currentPrincipalAccessor.Change(identity))
            {
                await _abpClaimsPrincipalFactory.CreateAsync(principal);
            }
    
            return principal;
        }
    }
    
    
Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11