关于 c#:Authorize 属性重定向到 LoginPath 而不是 AccessDeniedPath

Authorize attribute redirects to LoginPath instead of AccessDeniedPath

我对应用程序 cookie 有以下配置:

1
2
3
4
5
6
services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = $"/Identity/LogIn";
    options.LogoutPath = $"/Identity/LogOut";
    options.AccessDeniedPath = $"";
});

还有以下授权策略:

1
2
3
4
5
services.AddAuthorization(options =>
{
    options.AddPolicy("User", policy => policy.RequireClaim(ClaimTypes.Role,"User"));
    options.AddPolicy("Admin", policy => policy.RequireClaim(ClaimTypes.Role,"Admin"));
});

在创建用户时,我添加以下策略:

1
await _userManager.AddClaimsAsync(user, new[] {new Claim(ClaimTypes.Role,"User")});

然后我有一个带有管理策略的授权属性的虚拟操作,每当我尝试使用只有"用户"策略的帐户访问它时,我希望被重定向到 AccessDeniedPath,因为我已经登录在我没有登录时,我希望被重定向到 LoginPath,但是我总是被重定向到 LoginPath。

1
2
3
4
5
6
[Authorize(Policy ="Admin")]
[HttpGet]
public IActionResult Action()
{
    //..
}

所以简而言之,所需的行为是,每当用户尝试访问资源而不登录时我被重定向到 options.LoginPath = $"/Identity/LogIn" 并且每当用户登录但没有足够的权限时被重定向到 options.AccessDeniedPath = $""; .

我打算将同样的想法不仅应用于控制器,也应用于剃须刀页面。


Authorize 属性返回错误 401,通常会重定向到使用正确凭据登录。我相信在处理错误 403 时会使用 AccessDeniedPath

我们最近实现了一个自定义授权属性,专门用于处理 401 和 403 错误的分离。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[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
        }
    }        
}