为什么我的Cookie身份验证在ASP .NET Core中不起作用?

Dou*_*oug 2 authentication asp.net-core

我已启用使用Cookie的身份验证:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using WebBasic.Core.Controllers;

namespace WebBasic.Core
{
  public class Startup
  {
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddMvc();
      services.AddAuthentication().AddCookie(AuthController.AuthControllerAuthId);
      services.AddAuthorization(options => { options.AddPolicy("IsFoo", policy => policy.RequireClaim("FooType")); });
    }

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
    {
      app.UseMvc();
      app.UseAuthentication();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

...并创建了通用视图来测试声明:

using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;

namespace WebBasic.Core.Controllers
{
  [Route("/api/[controller]/[action]")]
  public class AuthController : Controller
  {
    public const string AuthControllerAuthId = "AuthControllerAuthId";

    public IActionResult Test()
    {
      var claims = string.Join(", ", User.Claims.Select(i => i.Type));
      return Ok($"{User.Identity.IsAuthenticated}: {claims}");
    }

    public async Task<IActionResult> AuthFixed()
    {
      var claims = new List<Claim> {new Claim("FooType", "FooValue", ClaimValueTypes.String)};
      var userIdentity = new ClaimsIdentity(claims);
      var userPrincipal = new ClaimsPrincipal(userIdentity);
      await HttpContext.SignInAsync(AuthControllerAuthId, userPrincipal);
      return Ok("ok");
    }

    public async Task<IActionResult> Logout()
    {
      await HttpContext.SignOutAsync(AuthControllerAuthId);
      return Ok("ok");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当我得到/api/auth/authfixed/一个cookie集时:

Cache-Control:no-cache
Content-Type:text/plain; charset=utf-8
Date:Tue, 05 Sep 2017 13:57:39 GMT
Expires:-1
Pragma:no-cache
Server:Kestrel
Set-Cookie:.AspNetCore.AuthControllerAuthId=...; path=/; samesite=lax; httponly
Run Code Online (Sandbox Code Playgroud)

...但是当我返回时,api/auth/test我得到:

False
Run Code Online (Sandbox Code Playgroud)

即。我没有认证?身份验证中间件没有获取我的cookie?为什么不?

如果添加,[Authorize]我得到:

System.InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.
at Microsoft.AspNetCore.Authentication.AuthenticationService.<ChallengeAsync>d__11.MoveNext()
Run Code Online (Sandbox Code Playgroud)

??? 为什么需要明确设置?

我知道,我可以将DefaultChallengeScene,DefaultAuthenticationScheme和DefaultScheme设置为CookieAuthenticationDefaults.AuthenticationScheme,但实际上所做的全部都设置为字符串“ Cookies”,但仍然不起作用。

这里到底发生了什么?

Dou*_*oug 5

对于任何其他有此问题的人,诀窍是您所有的组件都需要引用相同的身份ID。

就我而言,我使用的AuthControllerAuthId是自定义身份验证标识符,而不是default Cookie。我需要确保auth链的所有部分都使用此值。

添加身份验证时:

services.AddAuthentication(options =>
  {
    options.DefaultChallengeScheme = AuthController.AuthControllerAuthId;
    options.DefaultAuthenticateScheme = AuthController.AuthControllerAuthId;
    options.DefaultScheme = AuthController.AuthControllerAuthId;
  }).AddCookie(AuthController.AuthControllerAuthId)
Run Code Online (Sandbox Code Playgroud)

在构造时ClaimsIdentity

var userIdentity = new ClaimsIdentity(claims, AuthControllerAuthId);
var userPrincipal = new ClaimsPrincipal(userIdentity);
Run Code Online (Sandbox Code Playgroud)

登录时:

await HttpContext.SignInAsync(AuthControllerAuthId, userPrincipal);
Run Code Online (Sandbox Code Playgroud)

一切都是实际工作,但特别是在我的情况下,关键是要看看AuthenticationTypeUser.Identity,并确保其正确设置为所有步骤。