[解決済み】認証や認可に失敗した場合、AuthorizeAttributeがログインページにリダイレクトされるのはなぜですか?
質問
ASP.NET MVCでは、コントローラメソッドのマークアップに
AuthorizeAttribute
のようなものです。
[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
// ...
}
これは、現在ログインしているユーザーが "CanDeleteTags" ロールでない場合、コントローラメソッドが決して呼び出されないことを意味します。
残念ながら、失敗の場合。
AuthorizeAttribute
が返されます。
HttpUnauthorizedResult
は、常にHTTPステータスコード401を返します。これはログインページへのリダイレクトを引き起こします。
ユーザーがログインしていない場合、これは完全に理にかなっています。しかし、もしユーザーが すでに ログインしているが、必要なロールを持っていない場合、ログインページに戻すと混乱する。
どうやら
AuthorizeAttribute
は、認証と認可を混同しています。
これはASP.NET MVCのちょっとした見落としのような気がするのですが、それとも何か見落としているのでしょうか?
を料理することになったんだ。
DemandRoleAttribute
を分離しています。ユーザーが認証されていない場合、HTTP 401を返し、ログインページに送ります。ユーザーがログインしているが、必要なロールに属していない場合、HTTP 401を返し、ログインページに送ります。
NotAuthorizedResult
代わりに 現在、これはエラーページにリダイレクトされます。
確かに、こんなことする必要なかったかな?
解決方法は?
最初に開発されたとき、System.Web.Mvc.AuthorizeAttributeは正しいことを行っていました。 HTTP仕様の古いリビジョンでは、quot;unauthorized" と "unauthenticated" の両方にステータスコード401が使用されています。
元の仕様から。
<ブロッククオートリクエストがすでに認証情報を含んでいた場合、401応答はそれらの認証情報に対して認証が拒否されたことを示す。
実際、ここに混乱が見られます。「認証」を意味するのに「認可」という言葉を使っているのです。しかし、日常的には、ユーザが認証されているが認可されていない場合に403 Forbiddenを返す方が理にかなっています。ユーザーがアクセスするための2つ目の認証情報を持っている可能性は低く、全体として悪いユーザーエクスペリエンスになります。
ほとんどのオペレーティングシステムを考えてみましょう。アクセス権限のないファイルを読もうとしたとき、ログイン画面は表示されません。
ありがたいことに、HTTPの仕様が更新(2014年6月)され、曖昧さが解消されました。
From "ハイパーテキストトランスポートプロトコル(HTTP/1.1)。Authentication" (RFC 7235)より。
<ブロッククオート401(Unauthorized)ステータスコードは、ターゲットリソースに対する有効な認証情報がないため、リクエストが適用されなかったことを示す。
ハイパーテキスト転送プロトコル(HTTP/1.1)より。Semantics and Content" (RFC 7231)より。
<ブロッククオート403(Forbidden)ステータスコードは、サーバーがリクエストを理解したが、それを承認することを拒否したことを示します。
興味深いことに、ASP.NET MVC 1がリリースされた時点では、AuthorizeAttributeの動作は正しかったのです。現在では、その動作は正しくありません。HTTP/1.1の仕様が修正されたのです。
ASP.NETのログインページのリダイレクトを変更しようとするよりも、問題を根本的に解決する方が簡単です。同じ名前の新しい属性を作成することができます (
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);
}
}
}
関連
-
[解決済み] Visual Studioのデバッグ/ロードが非常に遅い
-
[解決済み] ELMAHをASP.NET MVCの[HandleError]属性で動作させる方法は?
-
[解決済み] 修正方法: ハンドラ "PageHandlerFactory-Integrated" のモジュールリストに "ManagedPipelineHandler" という不正なモジュールが含まれています。
-
[解決済み] ASP.NET MVCのビューを文字列としてレンダリングする方法は?
-
[解決済み] ASP.NET MVCでHTML-5のdata-*属性でダッシュを使用する方法
-
[解決済み】ViewModelのベストプラクティス
-
[解決済み] セキュリティ透過的なメソッド 'WebMatrix.WebData.PreApplicationStartCode.Start()' による試行。
-
[解決済み] MVCとRazorにおけるHtml.TextboxForとHtml.EditorForの相違点
-
[解決済み] ASP.NET MVC Html.ActionLinkにアンカータグを含める
-
[解決済み] Entity Frameworkのデータベースを再作成する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ファイルまたはアセンブリ 'System.Web.Mvc' を読み込めませんでした。
-
[解決済み] RedirectToActionのパラメータとしてmodelを渡すことはできますか?
-
[解決済み] Razor View throwing "The name 'model' does not exist in the current context".
-
[解決済み] MVC 3 - 辞書に渡されたモデル項目の型は 'System.Collections.Generic.List`1 です。
-
[解決済み】ASP.NET MVC 3 コントローラから200 HTTPステータスコードを返す方法
-
[解決済み】ASP.NET MVC 3 Razor - EditorForにクラスを追加する。
-
[解決済み】ViewModelのベストプラクティス
-
[解決済み] ASP.NET MVCにおけるセッション変数
-
[解決済み] ソートロジックは、モデル、ビュー、コントローラのいずれに配置するのがよいのでしょうか?[クローズド]
-
[解決済み] ASP.NET MVCとIIS7で生のHTTPリクエスト/レスポンスをログに記録する