我使用Owin的新Asp.Net标识启动了一个新的MVC 5站点。在我的“帐户”控制器中,它具有[授权]属性,我有相当标准的操作;
// 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]的控制器中调用一个动作,它将被发送到登录上面的操作然后返回到请求的控制器/操作。哪个好,但是怎么样?它安全吗?
在这篇关于“Preventing open redirect attacks”(对于早期版本的Asp.Net MVC)的文章中,建议在进行重定向之前检查一下returnUrl它是一个本地URL,这是我还应该做的事情是或现在由框架处理?
干杯, 奥拉
答案 0 :(得分:15)
您需要使用此方法检查网址是否确实是本地的(框架不会自动处理):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);
}
答案 1 :(得分:4)
正如Sandeep Phadke所说,由于startup.Auth.cs中的配置,returnUrl参数已填满。
CookieAuthenticationOptions有一个属性ReturnUrlParameter,默认设置为“returnUrl”。这就是为什么它看起来像魔术的原因。您可以将其更改为您想要的任何内容:
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();
}
答案 2 :(得分:3)
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Controller");
}
答案 3 :(得分:2)
要回答关于如何设置重定向网址的第一个问题,请在Startup.Auth.cs
中对其进行配置,该问题从Startup.cs
调用,并且标记有可能由应用上的OWIN框架查找的属性启动时,两个文件partial
都会扩展Startup
类。
在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的更多文档。