更新时间:2022-06-20 18:21:03
当它第一次开发,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);
}
}
}