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

时间:2016-05-03 01:21:01

标签: asp.net-core asp.net-identity .net-core

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

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

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

在下面的代码中,我可以调用p.IsInRole("ADMIN")并调用MyClaimsPrincipal.IsInRole()的实现并返回true。

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

[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. 如何? : - )

  3. 如果我不得不猜测,我没有正确实现p.IsInRole() - 目前此方法加载角色,然后返回True / False。也许我必须加载'我在其他地方的角色以ClaimsPrincipal.IsInRole就足够了。如果我使用Identity(),我认为这将是IUserRoleStore的实现。

    我的其他人如果我不得不猜测'答案是在startup.cs的某个地方我需要用ClaimsPrincipal的实例替换当前的MyClaimsPrincipal

    谢谢!

1 个答案:

答案 0 :(得分:3)

您应该在创建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);
}