我和我的团队正在ASP .NET 5中启动一个新的网站项目,我试图建立我们的用户身份验证和授权策略的基础。
我目前正在为返回用户使用基于cookie的身份验证,因此我已将以下内容添加到Startup.cs的Configure方法中:
// Redirect to login page if user is not logged in.
app.UseCookieAuthentication(options =>
{
options.AutomaticAuthentication = true;
options.ExpireTimeSpan = new System.TimeSpan(0, 1, 0);
options.SlidingExpiration = true;
options.LoginPath = "/Login";
options.ReturnUrlParameter = "ReturnUrl";
});
身份验证服务也会添加到ConfigureServices方法中。
我关注的是LoginPath参数:当我的中间件/过滤器(我试过两者)返回401代码时,自动重定向到登录页面正常工作,自动重定向从登录页面返回到最初请求的那个没有& #39;工作:即使成功登录,浏览器仍保留在登录页面上。
我强烈怀疑问题出在我控制器的某个地方。这是它的(略微简化的)源代码:
[Route("[controller]")]
[AllowAnonymous]
public class LoginController : Controller
{
private static readonly string AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme;
public IActionResult Index()
{
return View();
}
[HttpPost]
public async System.Threading.Tasks.Task<ActionResult> Post(LoginInfo infos)
{
if (ValidateLogin(infos))
{
await Context.Authentication.SignInAsync(AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Role, "Admin")
},
AuthenticationScheme)));
}
return View("Index");
}
private static bool ValidateLogin(LoginInfo infos)
{
return infos.Username == "abc" && infos.Password == "def";
}
}
(为清晰起见,删除了一些代码,例如,如果拒绝用户名/密码组合,则显示错误消息)
视图非常简单,包含一个简单的表单,提供了几个编辑框并将用户/密码发布到控制器(同样,为清晰起见,删除了错误消息):
@using (Html.BeginForm("Post", "Login", FormMethod.Post))
{
<div>
<h2>Login Page</h2>
<p>
@Html.Label("Username")
@Html.Editor("Username")
</p>
<p>
@Html.Label("Password")
@Html.Password("Password")
</p>
<p>
<input type="submit" value="Attempt login" />
</p>
</div>
}
我已经能够通过在单独的控制器中获取用户身份和声明来检查用户登录是否正常工作。初始重定向到登录页面也可以正常工作(即,当我尝试访问网站的受保护部分而未登录时,我被重定向到&#39; /登录&#39;并且重定向的URL正确包含ReturnUrl查询参数。我还尝试在处理Post操作时访问Referer URL并设法通过从控制器手动返回RedirectResult来强制触发重定向,因此ReturnUrl本身的内容也必须良好。
那么......任何人都可以帮助我理解为什么不会自动重定向到返回URL吗?
编辑:根据CookieAuthenticationOptions.LoginPath:
的文档要点: LoginPath属性通知中间件它应该更改传出 401未授权的状态代码到302重定向到给定的登录路径。 生成401的当前url作为查询添加到LoginPath 由ReturnUrlParameter命名的字符串参数。 一旦请求到LoginPath 授予新的SignIn标识,ReturnUrlParameter值用于重定向 浏览器返回到导致原始未授权状态代码的URL。 如果LoginPath为null或为空,则中间件不会查找401 Unauthorized 状态代码,并且在登录时不会自动重定向。
粗体部分是我试图利用的部分......重定向到静态页面(即手动将Redirect()手动返回到某个硬编码页面)并不是我想要实现的目标这里。
答案 0 :(得分:0)
问题是您在成功登录后总是返回索引视图:
[HttpPost]
public async System.Threading.Tasks.Task<ActionResult> Post(LoginInfo infos)
{
if (ValidateLogin(infos))
{
await Context.Authentication.SignInAsync(AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Role, "Admin")
},
AuthenticationScheme)));
}
return View("Index"); //the problem is here
}
尝试将return View("Index");
替换为您要将用户重定向到的视图(可能在另一个控制器上)。您可以尝试RedirectToAction:Redirect to Action in another controller。类似的东西:
return RedirectToAction("Index", "Home");
在您的情况下,如果您依赖框架为您进行重定向,请尝试:
[HttpPost]
public async System.Threading.Tasks.Task Post(LoginInfo infos)
{
if (ValidateLogin(infos))
{
await Context.Authentication.SignInAsync(AuthenticationScheme, new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Role, "Admin")
},
AuthenticationScheme)));
}
}