使用没有 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();
}
}
不使用Identity,只使用Cookie中间件时,可以使用[Authorize(Roles = "ADMIN")]
属性吗?
怎么样? :-)
如果非要我猜的话,我没有正确实施 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);
}
为了保持与现有应用程序的兼容性,我计划使用没有 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();
}
}
不使用Identity,只使用Cookie中间件时,可以使用
[Authorize(Roles = "ADMIN")]
属性吗?怎么样? :-)
如果非要我猜的话,我没有正确实施 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);
}