使用没有 ASP.NET 标识的 Cookie 中间件时的自定义 IsInRole()

Custom IsInRole() when using Cookie Middleware without ASP.NET Identity

为了保持与现有应用程序的兼容性,我计划使用没有 ASP.NET Identity 的 Cookie 中间件,如文档中所述:

https://docs.asp.net/en/latest/security/authentication/cookie.html

就用户登录而言,这似乎按预期工作,但我在角色方面遇到了问题——特别是在使用 [Authorize(Roles = "ADMIN")].

在下面的代码中,我可以调用 p.IsInRole("ADMIN") 并调用我的 MyClaimsPrincipal.IsInRole() 实现并且 returns 为真。

不起作用的是 [Authorize(Roles = "ADMIN")] 属性,因为它最终调用 ClaimsPrincipal.IsInRole(returns False)而不是 MyClaimsPrincipal.IsInRole()(returns 正确)。

[Authorize(Roles = "ADMIN")]
public class MyAdminController : Controller
{
    public IActionResult Index()
    {
        var p = new MyClaimsPrincipal(ClaimsPrincipal.Current);

        bool isAdmin = p.IsInRole("ADMIN");

        return View();
    }
}
  1. 不使用Identity,只使用Cookie中间件时,可以使用[Authorize(Roles = "ADMIN")]属性吗?

  2. 怎么样? :-)

如果非要我猜的话,我没有正确实施 p.IsInRole() -- 当前此方法加载角色,然后 returns 和 True/False。也许我必须 'load' 我在其他地方的角色,这样 ClaimsPrincipal.IsInRole 就足够了。如果我使用 Identity(),我假设这将是 IUserRoleStore.

的实现

我的另一个 'if i had to guess' 答案是 startup.cs 中的某处我需要用 MyClaimsPrincipal.

的实例替换当前的 ClaimsPrincipal

谢谢!

您应该在创建 cookie 时添加角色声明。

在startup.cs中:

app.UseCookieAuthentication(options =>
{
     options.AuthenticationScheme = "MyCookieMiddlewareInstance";
     options.LoginPath = new PathString("/Account/Login/");
     options.AccessDeniedPath = new PathString("/Account/Forbidden/");
     options.AutomaticAuthenticate = true;
     options.AutomaticChallenge = true;
 });

和登录 post 方法可能是这样的(我假设你有一个自定义登录页面):

[HttpPost]
public IActionResult Login(string userName, string password, string returnUrl)
{
     var user = _userService.GetUser(userName, password);// i assume that  _userService is injected
     if (user == null)
     {
          //return Error;
     }
     var claims = new List<Claim>()
     {
          new Claim(ClaimTypes.NameIdentifier, user.Id),
          new Claim(ClaimTypes.Name, user.GetFullName() ),
     };
     var identity = new ClaimsIdentity(claims, "Forms");
     identity.AddClaim(new Claim(ClaimTypes.Role, "ADMIN"));
     var principal = new ClaimsPrincipal(identity);

     HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);
     return Redirect(returnUrl);
}