Asp.net MVC4: コントローラとアクションの両方で認証する
質問
コントローラとアクションの両方にAuthorize属性がある場合、どちらが効果を発揮するのでしょうか?それとも両方が効果を発揮するのでしょうか?
どのように解決するのですか?
という質問がありました。
コントローラとアクションの両方にAuthorize属性がある場合、どちらが効果を発揮するのでしょうか?両方ですか?
簡単にお答えすると 両方です。その効果は
AND
という2つの制限を一緒にしてしまうことです。以下にその理由を説明します.
詳細
では、このような質問をされる理由はいくつかあります。
-
メソッドと比較して、アクションに追加の制約を強制する方法を知りたい場合。
- コントローラレベルでは、ロール "user"のユーザーを強制する。
- アクションレベルでは、さらに "admin" のロールのユーザーを強制します。
- アクションレベルでコントローラー制約を置き換えたい場合
- アクションレベルでのコントローラ制約を削除し、匿名ユーザーがメソッドを使用できるようにしたい。
MVCのバージョンが明記されていないので、今日現在の最新版(MVC 4.5)と仮定します。ただし、MVC 3 を使用していたとしても、回答はあまり変わりません。
[Anonymous]
はコントローラをオーバーライドします。
[Authorize]
(ケース3)
ケース3 カバーする必要がない(使用するのは
[AllowAnonymous]
) が回答されているため
SOの至る所で
と
ウェブ上の至る所で
を指定することができます。もしあなたが
[AllowAnonymous]
を指定すると、たとえコントローラがそのアクションを公開することになります。
[Authorize]
がついていたとしても、そのアクションは公開されます。
また、ウェブサイト全体を認証の対象とするには、次のようにします。
グローバルフィルタを使って
を使用し、さらに
AllowAnonymous
を使用してください。
[Authorize]
は加算式(ケース1)
ケース1は簡単です。次のコントローラを例にとります。
[Authorize(Roles="user")]
public class HomeController : Controller {
public ActionResult AllUsersIndex() {
return View();
}
[Authorize(Roles = "admin")]
public ActionResult AdminUsersIndex() {
return View();
}
}
デフォルトでは
[Authorize(Roles="user")]
は、Controller内の全てのActionを、"user"ロールのアカウントのみが利用できるようにします。そのため
AllUsersIndex
にアクセスするには、"user" ロールに属している必要があります。しかし
AdminUsersIndex
にアクセスするには、"user" と "admin" ロールの両方である必要があります。例えば
-
ユーザー名: Bob, ロール: user,
はできません
アクセス
AdminUsersIndex
にはアクセスできませんがAllUsersIndex
-
ユーザー名: Jane, ロール: admin,
できません
アクセス
AdminUsersIndex
またはAllUsersIndex
-
ユーザー名: Tim, 役割: user & admin,
できます
アクセス
AdminUsersIndex
とAllUsersIndex
これは
[Authorize]
属性が加法的であることを示している。これは
Users
属性のプロパティと組み合わせることができ、これは
Roles
と組み合わせることで、さらに制限を強めることができます。
この動作は、controller属性とaction属性の動作に起因しています。属性は連鎖しており、controller、actionの順で適用されます。もし最初のものが認可を拒否した場合、controlは戻り、actionの属性は呼び出されません。もし最初のものが認証を通れば、2 番目のものも同様にチェックされます。この順序を上書きするには
Order
(例えば
[Authorize(Roles = "user", Order = 2)]
).
オーバーライド
[Authorize]
(ケース2)
ケース2はよりトリッキーです。上記から思い出してください。
[Authorize]
属性は (Global then) Controller, Action の順に検査されます。ユーザーが認証される資格がないことを最初に検出したものが勝利し、他のものは呼び出されないのです。
これを回避する一つの方法は、以下のように2つの新しい属性を定義することです。その
[OverrideAuthorize]
には何もせず、ただ
[Authorize]
その唯一の目的は、チェックすることができる型を定義することです。そのため
[DefaultAuthorize]
によって、リクエストの中で呼び出されるアクションが
[OverrideAuthorize]
. もしそうなら Action の認証チェックに進み、そうでなければ Controller レベルのチェックに進みます。
public class DefaultAuthorizeAttribute : AuthorizeAttribute {
public override void OnAuthorization(AuthorizationContext filterContext)
{
var action = filterContext.ActionDescriptor;
if (action.IsDefined(typeof(OverrideAuthorizeAttribute), true)) return;
base.OnAuthorization(filterContext);
}
}
public class OverrideAuthorizeAttribute : AuthorizeAttribute {
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
}
}
すると、このように使うことができます。
[DefaultAuthorize(Roles="user")]
public class HomeController : Controller {
// Available to accounts in the "user" role
public ActionResult AllUsersIndex() {
return View();
}
// Available only to accounts both in the "user" and "admin" role
[Authorize(Roles = "admin")]
public ActionResult AdminUsersIndex() {
return View();
}
// Available to accounts in the "superuser" role even if not in "user" role
[OverrideAuthorize(Roles = "superuser")]
public ActionResult SuperusersIndex() {
return View();
}
}
上記の例では
SuperusersIndex
は、"user"ロールを持たないアカウントであっても、"superuser"ロールを持つアカウントで利用可能です。
関連
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み] クライアントから危険な可能性のあるRequest.Formの値が検出された
-
[解決済み] ASP.NET MVCコントローラは、Imageを返すことができますか?
-
[解決済み] JSONまたは部分的なhtmlを返すASP.NET MVCコントローラのアクション
-
[解決済み] ASP.NET MVCにおけるApiControllerとControllerの相違点
-
[解決済み] ASP.NET MVCでコントローラのメソッドをオーバーロードすることはできますか?
-
[解決済み】ASP.NET MVCビューで現在のアクションを返すにはどうすればいいですか?
-
[解決済み】Html.ActionLinkを使用して別のコントローラのアクションを呼び出す
-
[解決済み] コントローラ名とアクション名をコントローラ内から取得する?
-
[解決済み] MVCとRazorにおけるHtml.TextboxForとHtml.EditorForの相違点
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】VS 2015でコントローラからビューを追加できない : "選択されたコードジェネレータの実行にエラーが発生しました"
-
[解決済み] glyphicons-halflings-regular.woff2 not foundに関するエラーを削除する方法
-
[解決済み] HTTPヘッダを送信した後、サーバーがステータスを設定できない IIS7.5
-
[解決済み] ルート値を含むURL.Action()
-
[解決済み] 既存のデータベースの選択されたテーブルからDbContextをScaffoldすることができますか[重複]。
-
[解決済み] ASP.NET MVCのビューを文字列としてレンダリングする方法は?
-
[解決済み】ASP.NET MVC Html.ValidationSummary(true) でモデルエラーが表示されない。
-
[解決済み] [Solved] ASP.NET MVCコントローラメソッドからJSON.NETでシリアライズされたcamelCase JSONを返すにはどうすればよいですか?
-
[解決済み】AutoMapper.CreateMapsをどこに配置するか?
-
[解決済み] ASP.NET MVCとIIS7で生のHTTPリクエスト/レスポンスをログに記録する