最初に開発されたとき、System.Web.Mvc.AuthorizeAttribute は正しいことを行っていました。HTTP 仕様の古いリビジョンでは、"unauthorized" と "unauthenticated" の両方にステータス コード 401 を使用していました。
元の仕様から:
リクエストに承認資格情報がすでに含まれている場合、401 応答は、それらの資格情報に対する承認が拒否されたことを示します。
実際、ここで混乱が見られます。「認証」を意味するときに「承認」という言葉を使用しています。ただし、日常的には、ユーザーが認証されているが許可されていない場合に 403 Forbidden を返す方が理にかなっています。ユーザーがアクセスを許可する 2 番目の資格情報セットを持っている可能性は低いです - 全体的に悪いユーザー エクスペリエンスです。
ほとんどのオペレーティング システムを考えてみてください。アクセス許可のないファイルを読み込もうとしても、ログイン画面は表示されません。
ありがたいことに、あいまいさを取り除くために HTTP 仕様が更新されました (2014 年 6 月)。
「ハイパー テキスト トランスポート プロトコル (HTTP/1.1): 認証」 (RFC 7235) から:
401 (Unauthorized) ステータス コードは、ターゲット リソースの有効な認証資格情報が不足しているため、リクエストが適用されなかったことを示します。
「ハイパーテキスト転送プロトコル (HTTP/1.1): セマンティクスとコンテンツ」(RFC 7231) から:
403 (Forbidden) ステータス コードは、サーバーが要求を理解したが、承認を拒否したことを示します。
興味深いことに、ASP.NET MVC 1 がリリースされた時点では、AuthorizeAttribute の動作は正しいものでした。現在、動作は正しくありません - HTTP/1.1 仕様が修正されました。
ASP.NET のログイン ページのリダイレクトを変更しようとするよりも、問題の発生源を修正する方が簡単です。Web サイトのデフォルトの名前空間にAuthorizeAttribute
同じ名前 ( )の新しい属性を作成できます(これは非常に重要です)。そうすれば、コンパイラは MVC の標準の名前空間の代わりに自動的にそれを取得します。もちろん、その方法を採用したい場合は、いつでも属性に新しい名前を付けることができます。
[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);
}
}
}