ASP.NET Core 2.2身份验证不起作用

时间:2019-11-25 17:02:48

标签: c# authentication asp.net-core asp.net-core-2.2

我正在尝试创建自己的登录身份验证,但是该身份验证无法正常工作,因此我创建了此快速测试...

[HttpGet]
public IActionResult Index()
{
    try
    {
        var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
        identity.AddClaim(new Claim(ClaimTypes.Name, "Test Name"));
        var principal = new ClaimsPrincipal(identity);

        SignIn(principal, CookieAuthenticationDefaults.AuthenticationScheme);

        var isAuthenticated = User.Identity.IsAuthenticated;    //-- THIS IS ALWAY FALSE... BUI JUST LOGGED IN?!?!?!?

        return View();
    }
    catch(Exception ex)
    {
        _logger.LogError(ex, "Error:");
        return StatusCode(500);
    }
}

因此您可以看到我呼叫SignIn,然后在下一行中检查用户是否已通过身份验证,但它始终返回false,并且User.Identity看上去也为空。有人知道我在做什么错吗?

在我的Startup / ConfigureServices中,我有:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(
    CookieAuthenticationDefaults.AuthenticationScheme,
    options =>
    {
        options.LoginPath = "/Admin/Index";
    });

然后在“启动/配置”中

app.UseAuthentication();
app.UseCookiePolicy(new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict,
});

3 个答案:

答案 0 :(得分:1)

SignIn(principal, CookieAuthenticationDefaults.AuthenticationScheme);

这是无人操作。 SignIn是一种创建SignInResult实例的便捷方法,通常会从操作中返回。这遵循命令模式,但是您的示例仅创建命令而从不执行。

您真正想要的是以下内容:

await HttpContext.SignInAsync(principal);

您可以根据需要提供该方案,但是您已将CookieAuthenticationDefaults.AuthenticationScheme中的ConfigureServices设置为默认方案,因此可以假定。

但是,即使进行了此更改,在提出另一个请求之前,User.Identity.IsAuthenticated仍将是false。通常,您会执行以下操作:

await HttpContext.SignInAsync(principal);

return RedirectToAction(...);

在设置后,调用SignInAsync最终将创建一个存储身份验证信息的cookie。它不会更新当前的User。在由重定向引起的下一个请求中,您的ASP.NET Core应用将读取cookie,并正确填充User

答案 1 :(得分:0)

我看到您的Index方法缺少Authorize属性。请添加Authorize属性,如下所示:

[Authorize]
[HttpGet]
public IActionResult Index()
{
    ....
}

然后在Configure类的Startup方法中,中间件顺序应如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
        ......

        app.UseStaticFiles();
        app.UseCookiePolicy(new CookiePolicyOptions
        {
            MinimumSameSitePolicy = SameSiteMode.Strict,
        });

        app.UseAuthentication();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
}

现在它应该对您有用。

答案 2 :(得分:0)

这是SignIn

的源代码
public virtual SignInResult SignIn(
  ClaimsPrincipal principal,
  string authenticationScheme)
=> new SignInResult(authenticationScheme, principal);

以上代码仅返回对象SignInResult,该对象此时不执行任何操作。

这是SignInResult的源代码: https://github.com/aspnet/Mvc/blob/master/src/Microsoft.AspNetCore.Mvc.Core/SignInResult.cs

这是核心代码:

public class SignInResult : ActionResult
{

    /// <inheritdoc />
    public override async Task ExecuteResultAsync(ActionContext context)
    {
        ...
        await context.HttpContext.SignInAsync(AuthenticationScheme, Principal, Properties);
    }
}

这是一个返回类型ActionResult,它只是调用context.HttpContext.SignInAsync,因此ControllerBase.SignInHttpContext.SignInAsync()的一种快捷方式。

但是!看一下以下ActionResult

public abstract class ActionResult : IActionResult
{
  public virtual Task ExecuteResultAsync(ActionContext context)
  {
   this.ExecuteResult(context);
   return Task.CompletedTask;
  }

  public virtual void ExecuteResult(ActionContext context)
  {
  }
}

因此SignInResultSync方法上什么也不做,而只在Async上做。

我可以建议的是:

  1. 在您的测试方法中,您只能return SignIn(...),然后该操作将自动执行,然后您可以在下一个请求中检查其授权。
  2. 如果您要登录并一次执行其他操作,请直接使用HttpContext.SignInAsync(),它是当前代码。
  3. [此选项很有趣]仅关于SignInResult实现的async函数,但是在sync方法中什么也不做,因此您可以尝试将测试操作更改为{ {1}}