1. ホーム
  2. .net

[解決済み] ASP.NET MVCで動的なログインURLにリダイレクトする方法

2023-02-03 12:53:31

質問

クライアントのためのページをホストするマルチテナンシー Web サイトを作成しています。URL の最初のセグメントは、クライアントを識別する文字列で、次の URL ルーティング スキームを使用して Global.asax で定義されます。

"{client}/{controller}/{action}/{id}"

これは、/foo/Home/IndexのようなURLで、問題なく動作します。

しかし、[Authorize] 属性を使用する場合、同じマッピングスキームを使用するログインページにリダイレクトさせたいと考えています。つまり、クライアントが foo の場合、ログイン ページは web.config で定義された固定 /Account/Login リダイレクトではなく /foo/Account/Login となります。

MVC は HttpUnauthorizedResult を使用して 401 の未承認ステータスを返し、これにより ASP.NET は web.config で定義されたページにリダイレクトされると推測されます。

ASP.NET のログイン リダイレクト動作をオーバーライドする方法を知っている人はいますか? または、カスタムの認可属性を作成することによって MVC でリダイレクトする方が良いでしょうか?

EDIT - 回答。 .Netのソースをいくつか調べた結果、カスタム認証属性が最良の解決策であると判断しました。

public class ClientAuthorizeAttribute: AuthorizeAttribute
{
    public override void OnAuthorization( AuthorizationContext filterContext )
    {
        base.OnAuthorization( filterContext );

        if (filterContext.Cancel && filterContext.Result is HttpUnauthorizedResult )
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary
                {
                    { "client", filterContext.RouteData.Values[ "client" ] },
                    { "controller", "Account" },
                    { "action", "Login" },
                    { "ReturnUrl", filterContext.HttpContext.Request.RawUrl }
                });
        }
    }
}

どのように解決するのですか?

主な問題は、組み込みの ASP.NET FormsAuthentication クラスに依存する場合 (そして、依存しない正当な理由がない場合)、1 日の終わりに何かで FormsAuthentication.RedirectToLoginPage() を呼び出し、設定された 1 つの URL を調べることになります。ログインURLは1つだけです。

この問題に対する私の対策 (おそらくルーブ・ゴールドバーグ実装) は、すべてのクライアントによって共有されるルートでの単一のログイン ページ、たとえば /account/login にリダイレクトさせることです。このログインページは実際には何も表示しません。ReturnUrl パラメータか、セッションで得た値か、クライアントを識別するクッキーを検査し、それを使って特定の /client/account/login ページに直ちに 302 リダイレクトを発行するのです。これは余分なリダイレクトですが、おそらく目立つことはなく、内蔵のリダイレクト機構を使用することができます。

もうひとつの方法は、あなたが説明したように独自のカスタム属性を作成することです。 RedirectToLoginPage() メソッドを呼び出すものを避けることです。 FormsAuthentication メソッドを作成し、それを独自のリダイレクトロジックに置き換えることになります。(静的なクラスなので、独自の代替インターフェースを注入して、既存の [Authorize] 属性と魔法のように連動させることができるようなメカニズムには気づいていません。 の人たちは以前にも同じようなことを .

お役に立てれば幸いです。