首页 文章

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

提问于
浏览
3

我的团队和我正在ASP .NET 5中启动一个新的网站项目,我正在尝试 Build 我们的用户身份验证和授权策略的基础 .

我目前正在为返回用户使用基于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";
    }
}

(为清楚起见,删除了一些代码,例如,如果拒绝用户名/密码组合,则显示错误消息)

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

@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查询参数 . 我还尝试在处理Post操作时访问Referer URL并设法通过从控制器手动返回RedirectResult来强制触发重定向,因此ReturnUrl本身的内容也必须良好 .

所以......任何人都可以帮助我理解为什么不会自动重定向到返回URL?

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

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

粗体部分是我想要利用的部分......重定向到静态页面(即手动将Redirect()手动返回到某个硬编码页面)并不是我想要在这里完成的 .

1 回答

  • 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"); 替换为您要将用户重定向到的视图(可能在另一个控制器上) . 你可以试试RedirectToActionRedirect 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)));
            }
     }
    

相关问题