Open Closed

How to customize claims #1013


User avatar
0
sgal created
  • ABP Framework version: v4.2.1
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • I used the Tiered structure to develop, but when I was customizing the claims, I encountered some problems. Whether it was inheriting AbpUserClaimsPrincipalFactory and overriding the CreateAsync method, or implementing the IAbpClaimsPrincipalContributor interface, there were problems, but some people in the community said he could. I have done a lot of tests and found that it is normal in the project of the Not Tiered structure, but the Tiered structure does not work normally. Can this problem be solved as soon as possible, or is there another way to implement it?
  • related issue
    • [ICurrentUser #42](https://github.com/abpframework/abp/issues/42)
    • [When I create the code in your way, the class no work and breakpoints .Could you help me? #7973](https://github.com/abpframework/abp/issues/7973)
  • Steps to reproduce the issue: Using the BookStore example, create Tired and Not Tired respectively,add the following classes
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Uow;
using IdentityRole = Volo.Abp.Identity.IdentityRole;
using IdentityUser = Volo.Abp.Identity.IdentityUser;

namespace Hang.Blog.Web.MyIdentity
{
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(AbpUserClaimsPrincipalFactory))]
    public class MyUserClaimsPrincipalFactory :
        AbpUserClaimsPrincipalFactory, ITransientDependency
    {

        public MyUserClaimsPrincipalFactory(
            UserManager<IdentityUser> userManager, 
            RoleManager<IdentityRole> roleManager,
            IOptions<IdentityOptions> options, 
            ICurrentPrincipalAccessor currentPrincipalAccessor, 
            IAbpClaimsPrincipalFactory abpClaimsPrincipalFactory) :
            base(userManager, roleManager, options, currentPrincipalAccessor, abpClaimsPrincipalFactory)
        {

        }


        [UnitOfWork]
        public override async Task<ClaimsPrincipal> CreateAsync(Volo.Abp.Identity.IdentityUser user)
        {

            var principal = await base.CreateAsync(user);
            principal.Identities
                .First().AddClaim(new Claim("Test", "123"));
            return principal;
        }
    }

}

or

using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Users;

namespace BookStore
{
    public class MyAbpClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
    {
        private readonly IdentityUserManager _identityUserManager;

        public MyAbpClaimsPrincipalContributor(
            IdentityUserManager identityUserManager)
        {
            _identityUserManager = identityUserManager;
        }
        
        public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
        {
            var identityUser = await _identityUserManager.GetUserAsync(context.ClaimsPrincipal);
            var organizationUnits = await _identityUserManager.GetOrganizationUnitsAsync(identityUser);
            
            
        }
    }
}

2 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Example:

    public class MyAbpClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
    {
        public Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
        {
            var claimsIdentity = new ClaimsIdentity();
            claimsIdentity.AddIfNotContains(new Claim("Organization", "OrganizationValue"));
            context.ClaimsPrincipal.AddIdentity(claimsIdentity);
    
            return Task.CompletedTask;
        }
    }
    
    public class MyAbpClaimsService : AbpClaimsService
    {
        public MyAbpClaimsService(IProfileService profile, ILogger<DefaultClaimsService> logger) : base(profile, logger)
        {
        }
    
        protected override IEnumerable<string> FilterRequestedClaimTypes(IEnumerable<string> claimTypes)
        {
            return base.FilterRequestedClaimTypes(claimTypes)
                .Union(new []{
                    AbpClaimTypes.TenantId,
                    AbpClaimTypes.EditionId,
                    "Organization"
                });
        }
    }
    
    
    context.Services.Replace(ServiceDescriptor.Transient<IClaimsService, MyAbpClaimsService>());
    
  • User Avatar
    0
    sgal created

    Hello, I try do this, and I realized that there was a problem with my previous understanding. I thought that the identity service was only used as a certification center, and then directly used dotnet run to run it. In the debug hostapi project, the rewritten code actually added needs to be called by the identity Server service Yes, the above two methods can be useful, but it is better to have a document description, thank you.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11