用户身份验证后自动重定向不工作

本文关键字:重定向 工作 身份验证 用户 | 更新日期: 2023-09-27 18:07:25

我和我的团队正在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代码时,自动重定向到登录页面的工作正确,从登录页面自动重定向到最初请求的页面不工作:浏览器仍然在登录页面上,即使成功登录后。

我强烈怀疑问题出在控制器的某个地方。下面是它的(稍微简化的)源代码:

[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";
    }
}

(为了清晰起见,删除了代码位,例如,如果用户名/pwd组合被拒绝,则显示错误消息)

视图非常简单,包含一个简单的表单,提供了几个编辑框,并将用户/密码发送给控制器(同样,为了清晰起见,删除了错误信息):

@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>
}

我已经能够通过在单独的控制器中获取用户身份和声明来检查用户登录是否正确工作。初始重定向到登录页面也可以正常工作(即当我试图访问网站的受保护部分而不登录时,我被重定向到'/login '),并且重定向的URL正确包含一个ReturnUrl查询参数。我还尝试访问Referer URL,同时处理Post操作,并设法通过手动从控制器返回redirecresult来强制触发重定向,因此ReturnUrl本身的内容也必须很好。

所以…谁能帮我理解为什么重定向到返回URL不自动执行?

编辑:根据CookieAuthenticationOptions的文档。LoginPath:

概要:LoginPath属性通知中间件它应该更改出站地址将未授权的状态码转换为302重定向到给定的登录路径。生成401的当前url作为查询添加到LoginPath由ReturnUrlParameter命名的字符串参数。一次请求到LoginPath授予一个新的SignIn标识,ReturnUrlParameter值用于重定向浏览器返回到导致原始未授权状态码的url。如果LoginPath为null或空,中间件将不会查找401 Unauthorized状态码,并且在发生登录时不会自动重定向。

粗体部分是我试图利用的…重定向到一个静态页面(即手动返回一个重定向()到一些硬编码的页面)不是我想在这里完成的。

用户身份验证后自动重定向不工作

问题是您总是在成功登录后返回到Index视图:

[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:重定向到Action。比如:

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)));
        }
 }