为什么AuthorizeAttribute重定向到登录页面进行身份验证和授权失败? [英] Why does AuthorizeAttribute redirect to the login page for authentication and authorization failures?

查看:6815
本文介绍了为什么AuthorizeAttribute重定向到登录页面进行身份验证和授权失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在ASP.NET MVC中,你可以标记与 AuthorizeAttribute 控制器方法,就像这样:

In ASP.NET MVC, you can mark up a controller method with AuthorizeAttribute, like this:

[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
    // ...
}

这意味着,如果当前登录的用户是不是在CanDeleteTags的作用,该控制器方法将永远不会被称为

This means that, if the currently logged-in user is not in the "CanDeleteTags" role, the controller method will never be called.

不幸的是,失败, AuthorizeAttribute 收益 HttpUnauthorizedResult ,它总是返回HTTP状态code 401本导致重定向到登录页面。

Unfortunately, for failures, AuthorizeAttribute returns HttpUnauthorizedResult, which always returns HTTP status code 401. This causes a redirection to the login page.

如果用户没有登录,这非常有意义。但是,如果用户的的登录,但不在所需的角色,这是混淆送他们回到登录页面。

If the user isn't logged in, this makes perfect sense. However, if the user is already logged in, but isn't in the required role, it's confusing to send them back to the login page.

似乎 AuthorizeAttribute 合并了认证和授权。

It seems that AuthorizeAttribute conflates authentication and authorization.

这似乎是一个位ASP.NET MVC的疏忽,还是我失去了一些东西?

This seems like a bit of an oversight in ASP.NET MVC, or am I missing something?

我已经煮了 DemandRoleAttribute 分隔两个。当用户没有通过验证,则返回HTTP 401,派他们到登录页面。当用户登录,但不是必需的作用,它会创建一个 NotAuthorizedResult 来代替。目前,该重定向到一个错误页面。

I've had to cook up a DemandRoleAttribute that separates the two. When the user isn't authenticated, it returns HTTP 401, sending them to the login page. When the user is logged in, but isn't in the required role, it creates a NotAuthorizedResult instead. Currently this redirects to an error page.

当然,我没有做到这一点?

Surely I didn't have to do this?

推荐答案

当它第一次开发,System.Web.Mvc.AuthorizeAttribute在做正确的事 -
对于HTTP规范使用状态code 401旧版的两个未经授权和未验证。

When it was first developed, System.Web.Mvc.AuthorizeAttribute was doing the right thing - older revisions of the HTTP specification used status code 401 for both "unauthorized" and "unauthenticated".

从原来规格:

如果请求中已经包含授权证书,那么401响应表示授权已拒绝这些凭据。

If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials.

事实上,你可以看到的混乱就在那里 - 它采用了核准一词时,它的意思是验证。在日常实践中,但是,它更有意义返回403,当用户进行身份验证,但无权禁止。这是不可能的用户将有第二组凭据,会给他们的访问 - 用户体验不好各地

In fact, you can see the confusion right there - it uses the word "authorization" when it means "authentication". In everyday practice, however, it makes more sense to return a 403 Forbidden when the user is authenticated but not authorized. It's unlikely the user would have a second set of credentials that would give them access - bad user experience all around.

考虑大多数操作系统 - 当你试图读取一个文件你没有权限访问,你不显示登录屏幕!

Consider most operating systems - when you attempt to read a file you don't have permission to access, you aren't shown a login screen!

幸运的是,HTTP规范进行了更新(2014年6月),以消除不确定性。

Thankfully, the HTTP specifications were updated (June 2014) to remove the ambiguity.

从超文本传输​​协议(HTTP / 1.1):身份验证(RFC 7235):

From "Hyper Text Transport Protocol (HTTP/1.1): Authentication" (RFC 7235):

在401状态code表示该请求没有被应用,因为它缺乏有效的认证证书为目标的资源。

The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource.

从超文本传输​​协议(HTTP / 1.1):语义和内容(RFC 7231):

From "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content" (RFC 7231):

403(禁止)状态code表示服务器理解请求,但拒绝授权。

The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it.

有趣的是,当时的ASP.NET MVC 1发布AuthorizeAttribute的行为是正确的。现在,该行为是不正确 - 在HTTP / 1.1规范固定

Interestingly enough, at the time ASP.NET MVC 1 was released the behavior of AuthorizeAttribute was correct. Now, the behavior is incorrect - the HTTP/1.1 specification was fixed.

而不是试图改变ASP.NET的登录页面重定向,它更容易只是为了从源头上解决问题。您可以创建在您的网站的默认命名空间相同的名称( AuthorizeAttribute 新的属性(这个很重要),那么编译器会自动拾取它,而不是MVC的标准之一。当然,你总是可以给属性的新名称,如果你宁愿采取这种做法。

Rather than attempt to change ASP.NET's login page redirects, it's easier just to fix the problem at the source. You can create a new attribute with the same name (AuthorizeAttribute) in your website's default namespace (this is very important) then the compiler will automatically pick it up instead of MVC's standard one. Of course, you could always give the attribute a new name if you'd rather take that approach.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

这篇关于为什么AuthorizeAttribute重定向到登录页面进行身份验证和授权失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆