为什么我的cookie身份验证不能在asp .net核心中运行?

时间:2017-09-05 14:10:30

标签: 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();
    }
  }
}

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

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

当我获得/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

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

False

即。我没有通过身份验证?身份验证中间件没有拿起我的cookie?为什么不呢?

如果我添加[Authorize],我会:

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

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

我知道,我可以将DefaultChallengeScene,DefaultAuthenticationScheme和DefaultScheme设置为CookieAuthenticationDefaults.AuthenticationScheme,但实际上的所有内容都设置为字符串'Cookies',但它仍然不起作用。

这里到底发生了什么?

1 个答案:

答案 0 :(得分:5)

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

在我的情况下,我使用AuthControllerAuthId作为我的自定义身份验证标识符,而不是默认的Cookie。我需要的是确保auth链的所有部分都使用此值。

添加身份验证时:

services.AddAuthentication(options =>
  {
    options.DefaultChallengeScheme = AuthController.AuthControllerAuthId;
    options.DefaultAuthenticateScheme = AuthController.AuthControllerAuthId;
    options.DefaultScheme = AuthController.AuthControllerAuthId;
  }).AddCookie(AuthController.AuthControllerAuthId)

构建ClaimsIdentity

var userIdentity = new ClaimsIdentity(claims, AuthControllerAuthId);
var userPrincipal = new ClaimsPrincipal(userIdentity);

登录时:

await HttpContext.SignInAsync(AuthControllerAuthId, userPrincipal);

一切都在运作,但在我的情况下,诀窍是查看AuthenticationType上的User.Identity并确保在所有步骤中正确设置。