为了保持与现有应用程序的兼容性,我计划使用不带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();
}
}
如果不使用Identity并仅使用 Cookie中间件,我可以使用[Authorize(Roles = "ADMIN")]
属性吗?
如何? : - )
如果我不得不猜测,我没有正确实现p.IsInRole()
- 目前此方法加载角色,然后返回True / False。也许我必须加载'我在其他地方的角色以ClaimsPrincipal.IsInRole
就足够了。如果我使用Identity(),我认为这将是IUserRoleStore
的实现。
我的其他人如果我不得不猜测'答案是在startup.cs的某个地方我需要用ClaimsPrincipal
的实例替换当前的MyClaimsPrincipal
。
谢谢!
答案 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);
}