それが最初に開発されたとき、System.Web.Mvc.AuthorizeAttributeは正しいことをしていました-HTTP仕様の古いリビジョンは、「無許可」と「非認証」の両方にステータスコード401を使用していました。
元の仕様から:
要求にすでに認証資格情報が含まれている場合、401応答は、それらの資格情報の認証が拒否されたことを示します。
実際、混乱がすぐにわかります。「認証」を意味する「認可」という言葉を使用しています。ただし、日常的には、ユーザーが認証されているが許可されていない場合は、403 Forbiddenを返す方が理にかなっています。ユーザーがアクセス権を与える2番目の資格情報セットを持つことはまずありません。
ほとんどのオペレーティングシステムを検討してください。アクセス権のないファイルを読み取ろうとすると、ログイン画面が表示されません。
ありがたいことに、あいまいさを取り除くためにHTTP仕様が更新されました(2014年6月)。
「ハイパーテキストトランスポートプロトコル(HTTP / 1.1):認証」(RFC 7235)から:
401(無許可)ステータスコードは、ターゲットリソースの有効な認証資格情報がないため、要求が適用されなかったことを示します。
「ハイパーテキスト転送プロトコル(HTTP / 1.1):セマンティクスとコンテンツ」(RFC 7231)から:
403(禁止)ステータスコードは、サーバーがリクエストを理解したが、承認を拒否したことを示します。
興味深いことに、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);
}
}
}