User.IsInRole() returns false 和授权角色给我拒绝访问
User.IsInRole() returns false and Authorize Roles gives me an Access Denied
我正在尝试使用 ASP.NET Core Identity 2.0 在我现有的应用程序中设置身份验证。因为我使用自己的数据库架构和 类,所以我有自己的用户和角色 类,我必须创建自定义 UserStore/UserManager/RoleStore/RoleManager.
我在我的服务中声明它们:
services.AddIdentity<User, Profile().AddUserManager<CustomUserManager<User>>().AddRoleManager<CustomRoleManager>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<User>, UserStore>();
services.AddTransient<IRoleStore<Profile>, ProfileStore>();
services.AddTransient<UserResolverService>();
我使用这些方法在 UserStore 中实现接口 UserRoleStore :
public Task AddToRoleAsync(User user, string roleName, CancellationToken cancellationToken)
{
user.Profiles.Add(db.Profiles.ToList().Find(x => x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase)));
db.SaveChanges();
return Task.FromResult((object)null);
}
public Task RemoveFromRoleAsync(User user, string roleName, CancellationToken cancellationToken)
{
user.Profiles.Remove(db.Profiles.ToList().Find(x => x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase)));
db.SaveChanges();
return Task.FromResult((object)null);
}
public Task<IList<string>> GetRolesAsync(User user, CancellationToken cancellationToken)
{
IList<string> ret = new List<string>();
user.Profiles.ToList().ForEach(x => ret.Add(x.Name));
return Task.FromResult(ret);
}
public Task<bool> IsInRoleAsync(Useruser, string roleName, CancellationToken cancellationToken)
{
Profile searchRole = db.Profiles.Include(profile => profile.ProfileUsers).ToList().Find(x => x.Active && x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase));
return Task.FromResult(searchRole.ProfileUsers.ToList().Find(x => x.UserID == user.ID) == null ? false : true);
}
public Task<bool> IsInRole(User user, string roleName, CancellationToken cancellationToken)
{
return Task.FromResult(true);
}
public Task<IList<Utilisateur>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken)
{
Profile currentProfile = db.Profiles.Include(profile => profile.ProfileUsers).ThenInclude(pu => pu.User).ToList().Find(x => x.Active && x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase));
if (currentProfile == null)
{
return Task.FromResult((IList<User>)null);
}
IList<User> ret = new List<User>();
currentProfile.ProfileUsers.ToList().ForEach(x => ret.Add(x.User));
return Task.FromResult(ret);
}
所以当我尝试做
var result1 = _userManager.AddToRoleAsync(userObject, "WorkOrderViewer");
var res = _userManager.GetUsersInRoleAsync("WorkOrderViewer");
var test = await _userManager.IsInRoleAsync(userObject, "WorkOrderViewer");
它有效,我的用户得到了选择的角色。但是,当我尝试在视图中设置控制器授权或控件可见性时,它不起作用。例如,对于控制器授权,我拒绝访问。
当我将其放入我的代码中时:
var test = User.IsInRole("WorkOrderViewer");
它 returns "false" 即使我正在登录应用程序(我尝试注销并登录)并且如果 UserManager.IsInRoleAsync returns 我 "true".
我认为它失败了,因为 UserManager.AddToRoleAsync() 与 User.IsInRole() 不同步,但我不知道如何解决它。
你知道我做错了什么吗?
当你说你使用代码 User.IsInRole
我假设你的意思是 Controller
.
User
in a controller is of type ClaimsPrincipal
.
方法 ClaimsPrincipal.IsInRole
具有以下文档:
The IsInRole method checks whether an identity that this claims principal possesses contains a claim of type ClaimsIdentity.RoleClaimType where the value of the claim is equal to the value specified by the role parameter.
这可以通过查看 source for ClaimsIdentity.cs 来确认。
if (_identities[i].HasClaim(_identities[i].RoleClaimType, role))
所以 User.IsInRole
正在检查用户是否有 RoleClaimType 类型的声明(默认为“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”)。
声明类型可以根据需要配置。
我正在尝试使用 ASP.NET Core Identity 2.0 在我现有的应用程序中设置身份验证。因为我使用自己的数据库架构和 类,所以我有自己的用户和角色 类,我必须创建自定义 UserStore/UserManager/RoleStore/RoleManager.
我在我的服务中声明它们:
services.AddIdentity<User, Profile().AddUserManager<CustomUserManager<User>>().AddRoleManager<CustomRoleManager>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<User>, UserStore>();
services.AddTransient<IRoleStore<Profile>, ProfileStore>();
services.AddTransient<UserResolverService>();
我使用这些方法在 UserStore 中实现接口 UserRoleStore :
public Task AddToRoleAsync(User user, string roleName, CancellationToken cancellationToken)
{
user.Profiles.Add(db.Profiles.ToList().Find(x => x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase)));
db.SaveChanges();
return Task.FromResult((object)null);
}
public Task RemoveFromRoleAsync(User user, string roleName, CancellationToken cancellationToken)
{
user.Profiles.Remove(db.Profiles.ToList().Find(x => x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase)));
db.SaveChanges();
return Task.FromResult((object)null);
}
public Task<IList<string>> GetRolesAsync(User user, CancellationToken cancellationToken)
{
IList<string> ret = new List<string>();
user.Profiles.ToList().ForEach(x => ret.Add(x.Name));
return Task.FromResult(ret);
}
public Task<bool> IsInRoleAsync(Useruser, string roleName, CancellationToken cancellationToken)
{
Profile searchRole = db.Profiles.Include(profile => profile.ProfileUsers).ToList().Find(x => x.Active && x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase));
return Task.FromResult(searchRole.ProfileUsers.ToList().Find(x => x.UserID == user.ID) == null ? false : true);
}
public Task<bool> IsInRole(User user, string roleName, CancellationToken cancellationToken)
{
return Task.FromResult(true);
}
public Task<IList<Utilisateur>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken)
{
Profile currentProfile = db.Profiles.Include(profile => profile.ProfileUsers).ThenInclude(pu => pu.User).ToList().Find(x => x.Active && x.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase));
if (currentProfile == null)
{
return Task.FromResult((IList<User>)null);
}
IList<User> ret = new List<User>();
currentProfile.ProfileUsers.ToList().ForEach(x => ret.Add(x.User));
return Task.FromResult(ret);
}
所以当我尝试做
var result1 = _userManager.AddToRoleAsync(userObject, "WorkOrderViewer");
var res = _userManager.GetUsersInRoleAsync("WorkOrderViewer");
var test = await _userManager.IsInRoleAsync(userObject, "WorkOrderViewer");
它有效,我的用户得到了选择的角色。但是,当我尝试在视图中设置控制器授权或控件可见性时,它不起作用。例如,对于控制器授权,我拒绝访问。
当我将其放入我的代码中时:
var test = User.IsInRole("WorkOrderViewer");
它 returns "false" 即使我正在登录应用程序(我尝试注销并登录)并且如果 UserManager.IsInRoleAsync returns 我 "true".
我认为它失败了,因为 UserManager.AddToRoleAsync() 与 User.IsInRole() 不同步,但我不知道如何解决它。 你知道我做错了什么吗?
当你说你使用代码 User.IsInRole
我假设你的意思是 Controller
.
User
in a controller is of type ClaimsPrincipal
.
方法 ClaimsPrincipal.IsInRole
具有以下文档:
The IsInRole method checks whether an identity that this claims principal possesses contains a claim of type ClaimsIdentity.RoleClaimType where the value of the claim is equal to the value specified by the role parameter.
这可以通过查看 source for ClaimsIdentity.cs 来确认。
if (_identities[i].HasClaim(_identities[i].RoleClaimType, role))
所以 User.IsInRole
正在检查用户是否有 RoleClaimType 类型的声明(默认为“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”)。
声明类型可以根据需要配置。