一部の WCF サービスのフロントエンドとして ASP.NET MVC 4 Web アプリケーションを使用しています。すべてのユーザーのログイン/ログアウトとセッション制御はバックエンドで行われます。MVC アプリは、セッション ID を持つ単一の Cookie のみを保存する必要があります。私のクライアントはフォーム認証の使用を許可していません。すべてをカスタマイズする必要があります。
web.config で次のように設定しました。
<system.web>
...
<authentication mode="None" />
</system.web>
<system.webServer>
<modules>
...
<remove name="FormsAuthentication" />
...
</modules>
</system.webServer>
グローバルフィルターもあります:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// Force all actions to request auth. Only actions marked with [AllowAnonymous] will be allowed.
filters.Add(new MyAuthorizeAttribute());
}
}
これは Global.asax で呼び出されます
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
承認を必要としないすべてのコントローラーとアクションに [AllowAnonymous] のマークを付けました。
そして今、MyAuthorizeAttribute を実装する必要があります。いくつかのチュートリアルを試しましたが、私のシナリオと完全に一致するものはありません。
基本的に、各アクションに対して次のシナリオを処理する必要があります。
- 有効な Cookie がある場合、現在のリクエストは承認されていると見なされます (確認する役割はなく、1 種類のユーザーのみです)。
- Cookie がない場合は、デフォルトの MVC ハンドラー (アカウント/ログインをロードしようとする) をオーバーライドし、ユーザーがログインする必要があるというメッセージを表示して、ユーザーをホーム/インデックス ページにリダイレクトする必要があります。
- WCF メソッド呼び出しが、カスタム SecurityFault がセッションの有効期限が切れたことを示す FaultException をスローした場合 (SecurityFault には、例外の理由を含むカスタム enum フィールドがあります)、カスタム セッション Cookie を破棄し、ユーザーを Home/Index ページに再度リダイレクトする必要があります。最後のセッションが期限切れになったため、ユーザーがログインする必要があるというメッセージ。他のすべての SecurityFaults については、通過させることができます。グローバル エラー ハンドラがあります。
私が理解している限り、AuthorizeCore (Cookie をチェックして、セッションが存在し、まだ有効かどうかを確認するため) と HandleUnauthorizedRequest (ユーザーをデフォルトのログイン ページではなくホーム/インデックスにリダイレクトするため) をオーバーライドする必要があります。
私が試したリダイレクトのために:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
filterContext.Result = new RedirectResult("/Home/Index/NeedsLogin");
}
これは、2番目のシナリオをうまく処理しているようです(ただし、そのベースコールについてはわかりません-必要ですか?)。
最初のシナリオでは、AuthorizeCore を実装する必要があります。よくわかりません、正しく行う方法。AuthorizeAttribute には、キャッシュの状況を処理するためのコードと、おそらくもっと多くの隠された機能があることがわかりましたが、それを壊したくありません。
3 番目のシナリオでは、MyAuthorizeAttribute で処理できるかどうかわかりません。AuthorizeAttribute はアクション内で発生する例外をキャッチできますか?それともグローバル エラー ハンドラで SecurityFault.SessionExpired の状況を処理する必要がありますか?