- ABP Framework version: v8.2.1
- UI Type: Angular
- Database System: EF Core (MySQL)
- Tiered (for MVC) or Auth Server Separated (for Angular): yes, Angular with Microservice Architecture
- Exception message and full stack trace:
- Steps to reproduce the issue:
Hello Team,
We have a microservices based architecture solution for our project. We don't want to use the TenantId in the AbpUsers and AbpRoles tables as per our requirements. For that what we have done is, we have kept separate tables (UserTenantAssociation and RoleTenantAssociation), using these tables we will determine which user belongs to which Tenant. And for the Roles, we will have all the Roles in the AbpRoles table with all records having TenantId as NULL, which implies the Roles will be created only in the Host Tenant and not any other Tenant. The other Tenants will be using the same Roles as Host, and which Tenants have which specific Roles to use in their tenant, that will be determined using our custom RoleTenantAssociation table where RoleId (the Id of the role from the host tenant) and the TenantId of that Tenant will be stored).
Now, displaying the list of Roles and Users on the UI doesn't seem to be a problem as we have already done necessary changes in the Users and Roles repositories in the IdentityService to achiever this feat. But the problem arises when the User logs into the Tenants.
Let's say I have a User which belongs to a Tenant, and the User has a role assigned to it as "admin", now in the AbpUserRoles table, the UserId will be the Id of the User from AbpUsers table, TenantId will be TenantId of the Tenant in which the user is trying to log into and the RoleId will be the Id of the Role "admin" from AbpRoles table but it will have TenantId as NULL as the Role belongs to the Host and the same Role should be used by all the Tenants.
Now if we run the application and when the user logs into a Tenant, it doesn't have any Roles assigned to it in the CurrentUser class, and also the GrantedPolicies will also be empty since there are no roles assigned to the user in the currentUser section of application configuration api call.
I tried to check how the values are assigned to the CurrentUser, and I came to know that it gets the values from the Claims generated during the Authentication and are passed to JWT Token during the authentication.
https://github.com/abpframework/abp/blob/8e20aab617205936c299ed5c3c40e0c529a3f06b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpUserClaimsPrincipalFactory.cs#L14
this is the code I tried :
public class AbpUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<IdentityUser, IdentityRole>, ITransientDependency { public AbpUserClaimsPrincipalFactory( UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager, IOptions<IdentityOptions> options) : base( userManager, roleManager, options) { }
[UnitOfWork]
public override async Task<ClaimsPrincipal> CreateAsync(IdentityUser user)
{
var principal = await base.CreateAsync(user).ConfigureAwait(false);
if (user.TenantId.HasValue)
{
principal.Identities
.First()
.AddClaim(new Claim(AbpClaimTypes.TenantId, user.TenantId.ToString()));
}
return principal;
}
}
(I tried this code in Administration Service Domain project)
but when using it, the login page will just stay there even after clicking the login button with correct credentials, it doesn't redirect to the angular app.
I want to know how exactly the CurrentUser is assigned these values and I want to override it because we have different logic of fetching the roles (from our custom table). I specifically want to know how the roles are assigned to the current user.
Right now, what I have done is, I have manually updated the value of the RoleId in the AbpUserRoles table, I have updated the RoleId with the one which belongs to the host. And because of that when the user logs into the application, there in, the api/abp/application-configuration?includeLocalizationResources=false api is called and in response of that API call, the grantedPolicies in the "auth" section is an empty array and in the "currentUser" section the roles is an empty array.
example : { "auth": { "grantedPolicies": [] }, "currentUser": { "roles": [], }, } So, given the scenario, how exactly can I set these granted policies and the currentUser values in the application when the user logs in?