我对应用程序cookie具有以下配置:
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/LogIn";
options.LogoutPath = $"/Identity/LogOut";
options.AccessDeniedPath = $"";
});
还有以下授权策略:
services.AddAuthorization(options =>
{
options.AddPolicy("User", policy => policy.RequireClaim(ClaimTypes.Role, "User"));
options.AddPolicy("Admin", policy => policy.RequireClaim(ClaimTypes.Role, "Admin"));
});
在创建用户时,我添加以下策略:
await _userManager.AddClaimsAsync(user, new[] {new Claim(ClaimTypes.Role, "User")});
然后,我有一个带有Admin策略的authorize属性的虚拟操作,每当我尝试使用仅具有'User'策略的帐户访问它时,由于我已经登录并且无论何时我都希望将其重定向到AccessDeniedPath我尚未登录,但我希望将其重定向到LoginPath。但是,我始终会重定向到LoginPath。
[Authorize(Policy = "Admin")]
[HttpGet]
public IActionResult Action()
{
//..
}
因此,期望的行为是,以便当用户尝试不登录而访问资源时,我就重定向到options.LoginPath = $"/Identity/LogIn"
,并且在用户登录但权限不足时就重定向到options.AccessDeniedPath = $"";
。
我打算将相同的想法不仅应用于控制器,而且也应用于剃须刀页面。
Authorize
属性返回错误401,通常会重定向到使用正确凭据的登录名。我认为,在处理错误403时会使用AccessDeniedPath
。
我们最近实现了一个自定义授权属性,专门用于处理401和403错误的分离。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class CustomAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
//If user is authenticated, send a 403 instead of 401
if (filterContext.HttpContext.Request.IsAuthenticated)
{
filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);//403
}
else
{
//if user is not authenticated, throw 401
base.HandleUnauthorizedRequest(filterContext); //401
}
}
}