Reputation: 141
We are implementing Multi-tenant architecture for our project.
userManager.CreateAsync(user, register.Password);
await roleManager.CreateAsync(new ApplicationRole("Admin", ParentCompanyId))
userManager.AddToRoleAsync(user, roleAdmin);
since our application is for multiple tenant and having Tenant wise Admin role in AspNetRoles
table so AddToRoleAsync()
is failing caz its not getting correct Admin role or having ambigious "Admin" role in AspNetRoles
table so throwing below exception. so can anyone guide me please how to add correct role to particular user. Since identity framework don't have any service to assign Role to user using RoleID
, it would have been simpler. Can anyone give solution for this approach or can suggest correct approach to add user to roles.
How to add User to Role using asp.net core Identity Framework services In Multi tenancy Architecture. I am not able to add user to Admin role tenantwise using userManager.AddToRoleAsync()
,
Receiving Below Exception on executing userManager.AddToRoleAsync(User,Role)
method
"System.InvalidOperationException: Enumerator failed to MoveNextAsync. at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken) at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9.IsInRoleAsync(TUser user, String normalizedRoleName, CancellationToken cancellationToken) at Microsoft.AspNetCore.Identity.UserManager`1.AddToRoleAsync(TUser user, String role) at Salon.Controllers.AccountController.SignUp(RegisterViewModel register) in C:\Users\Controllers\AccountController.cs:line 78"
Upvotes: 3
Views: 1331
Reputation: 1109
The way to do is to overwrite the default RoleStore and filter the roles by tenant in the custom RoleStore.
For this solution i'm assuming you are using SaasKit to resolve your tenants and your custom IdentityRole has a Tenant property.
If you look at the source code of UserManager.AddToRoleAsync they just use the provided RoleStore.
So if you look at the source code of the RoleStore, you can see all queries are done via Roles property. By adding a filter of tenants there you can always get the relevant Role assuming the tenant is resolved.
So the custom RoleStore:
public class TenantRoleStore : RoleStore<ApplicationRole<string>>
{
private readonly TenantContext<Tenant> _tenantContext;
public TenantRoleStore(
CustomDbContext context,
TenantContext<Tenant> tenantContext,
IdentityErrorDescriber describer = null)
: base(context, describer)
{
_tenantContext = tenantContext;
}
public override IQueryable<ApplicationRole<string>> Roles => base.Roles.Where(r => r.Tenant.Id == _tenantContext.Tenant.Id);
}
In the startup just add it where you configure Identity:
services.AddIdentity()
.AddRoleStore<TenantRoleStore>(); // <- add this
Upvotes: 4