web-dev-qa-db-ja.com

Asp.Net MVC5でreturnUrlにリダイレクトする方法

Owinで新しいAsp.Net Identityを使用して、新しいMVC 5サイトを開始しました。 [Authorize]属性を持つ「アカウント」コントローラーには、かなり標準的なアクションがあります。

   // GET: /User/Login
        [AllowAnonymous]
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        } 

// POST: /User/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var userApi = new UserService();
                    var apiUser = await userApi.LogIn(UserManager, model.CardNumber, model.Pin, model.RememberMe);

                    if (apiUser != null)
                    {
                        await SignInAsync(apiUser, model.RememberMe);
                        if (string.IsNullOrEmpty(returnUrl))
                        {                                   
                            return RedirectToAction("UserLoggedIn", "User");    
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("", "Invalid username or password.");
                    }
                }

            }
            catch (Exception ex)
            {
                Trace.TraceError("Cannot login {0}", ex.ToString());
                Response.AppendToLog(ex.ToString());
                ModelState.AddModelError("", ex.ToString());
            }
            // If we got this far, something failed, redisplay form
            return View(model);
        }

私の質問はreturnUrlの動作に関するものです。上記のコードは、ユーザーがログインしておらず、[Authorize]属性を持つコントローラーでアクションを呼び出すと、上記のログインアクションに送信され、次に、要求されたコントローラー/アクションに戻りました。どれが素晴らしいのですが、どうですか?そしてそれは安全ですか?

オープンリダイレクト攻撃の防止 "(Asp.Net MVCの以前のバージョンの場合)に関するこの記事では、リダイレクトを行う前に、returnUrlがローカルURLであることを確認することをお勧めします。私はまだやるべきですか、それともフレームワークによって処理されますか?

乾杯、オラ

10
Ola Karlsson

このメソッドを使用して、URLが実際にローカルであるかどうかを確認する必要があります(フレームワークによって自動的に処理されません)。 http://msdn.Microsoft.com/en-us/library/system.web.mvc。 urlhelper.islocalurl%28v = vs.118%29.aspx

if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
  return Redirect(returnUrl);
}
15
Marthijn

Sandeep Phadkeが言ったように、startup.Auth.csの構成により、returnUrlパラメーターが入力されています。

CookieAuthenticationOptionsには、デフォルトで「returnUrl」に設定されているプロパティReturnUrlParameterがあります。それが魔法のように見える理由です。あなたはそれをあなたが望むものに変更することができます:

app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        ReturnUrlParameter = "returnTo"
    });

次に、AccountController Login-Actionを次のように変更できます。

[AllowAnonymous]
    public ActionResult Login(string returnTo)
    {
        ViewBag.ReturnUrl = returnTo;
        return View();
    } 
4
Kirsten
       if (Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Controller");
        }
3
Vivekh

リダイレクトURLの設定方法に関する最初の質問に答えるために、Startup.Auth.csから呼び出され、Startup.csで構成され、アプリの起動時とその両方でOWINフレームワークによっておそらく検索される属性でマークされていますファイルpartialStartupクラスを拡張します。

Startup.Auth.csには、認証オプションを構成するクラスがあり、通常は次のコードがあります

public partial class Startup
{
    // For more information on configuring authentication, please visit http://go.Microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        // Enable the application to use a cookie to store information for the signed in user
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            CookieSecure = CookieSecureOption.Always
        });
        // Use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // ....
        // I deleted code which is commented out if you selected "Individual accounts" 
        // if you created the site project using the VS 2013 wizard
        // ...
    }
}

CookieSecureオプションを追加して、Cookieが確実に署名されるようにしました。これは、ボイラープレートコード以外に、優れたセキュリティ対策として推奨されています。

CookieAuthenticationOptions に関する詳細なドキュメントは、必要に応じてご覧ください。

2
Sandeep Phadke