ASP.NET标识检查用户角色不起作用



我有一个ASP.NET MVC 5应用程序。我使用标准的ASP.NET身份提供程序进行用户和角色管理。我使用自己的存储库项目中的IdentityUser很重要,但这似乎没问题。我可以注册、登录、编辑用户,并管理他们的角色。

我用以下行将用户添加到角色:

UserManager.AddToRole(userdetail.Id, r);
db.Entry(userdetail).State = EntityState.Modified;
db.SaveChanges();

这似乎在数据库级别起作用。

但是,我不能使用基于角色的身份验证,实际上是简单的

HttpContext.User.IsInRole("Administrator")

也不起作用。

[Authorize(Roles="Administrator")]

也不起作用。

我只能用这种方法检查用户是否是管理员:

UserManager.IsInRole(userID, "Administrator").

为什么?

在我发现的每一个教程中,一切都很好。不同的项目存储库可能是原因?还是ASP.NET标识被破坏了这么多?

请注意,

似乎有问题 [设计问题]

  • AuthorizeAttribute和User.IsInRole中的角色名称区分大小写
  • UserManager.IsInRole中的角色名称不区分大小写

此外,检查角色名称是否正确用于验证。

[以上是基于使用以下代码执行的测试。角色名称="管理员",用户被添加到角色"管理员"中。]

[Authorize(Roles="Admin")] /*True as "Admin" has A capital as entered in Role name*/
public ActionResult Secured()
{
    if (User.IsInRole("admin")) /*This is False*/
    {
         Console.WriteLine("In");
    }
    if(UserManager.IsInRole(User.Identity.GetUserId(), "admin")) /*This is True!!*/
    {
         Console.WriteLine("In");
    }
    return View();
}

如果我们将属性更改为[Authorize(Roles="admin")],它将重定向到登录页面。

在这种情况下,您需要注销并再次登录用户。

由于角色数据也存储在cookie中,因此,您必须再次发出cookie才能进行操作。

对我来说,上面的解决方案都不起作用,而且几乎所有的文章都没有起作用!问题是Authorize属性在身份服务器4发布的JWT令牌中搜索角色声明。默认情况下,标识服务器不会在具有标识的新项目上序列化令牌中的角色声明。

需要以下配置才能使其工作。(ASP.Net7新Blazor网页组装项目与身份)

builder.Services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
    options.IdentityResources["openid"].UserClaims.Add("role");
    options.ApiResources.Single().UserClaims.Add("role");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

ps。这也是最时尚的解决方案,因为大多数文章都需要覆盖和实现您自己的Identity Server主体工厂,并添加自定义身份资源等。

web.config中有这个条目吗?

    <roleManager enabled="true">
        <providers>
            <clear />
            <add connectionStringName="ApplicationServices" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" applicationName="/" />
        </providers>
    </roleManager>

此外,如果我没有记错的话,在不同版本的.NET.

中,角色提供程序集有一个不同的命名空间

我在Asp.Net核心中使用IsInRoleAsync,在我的情况下,问题是我在创建角色时忽略了它的规范化名称。因此,在更新角色的规范化姓名后,一切都正常工作。

我在一个.net7 webapi项目中遇到了完全相同的问题。以下是我的发现:

jwt令牌中的角色名称是NORMALIZE,因为Athorize属性区分大小写,所以我必须使用[Authorize(Roles="ADMIN"]而不是[Authorize[Roles="ADMIN&;]才能使角色工作。

为了避免这个陷阱,我终于把我所有的角色名称都设置为大写。

我认为JwtSecurityToken生成方法使用NORMALIZED角色名称来生成JWT令牌是我问题的根源。

无论如何,我认为Authrize Attribute和JwtSecurityToken应该给我们一个区分大小写的选项,或者至少警告我们这种区分大小写比较算法。

相关内容

  • 没有找到相关文章

最新更新