Cookie 身份验证无法在 JWT 身份验证 ASP.NET CORE 中正常工作



我正在练习使用 ASP.NET CORE编写Web应用程序,我遇到了Identity的问题。我尝试在线搜索,看看其他人是否遇到过这样的问题,但无济于事。

我构建了一个简单的 Web API,它使用 JWT 进行身份验证,一切正常。但我还需要使用户能够使用表单登录,即 cookie 身份验证。以下是我的配置服务方法。

private static void ConfigureJwt(IConfiguration configuration, IServiceCollection services)
{
services.AddSingleton<JwtSettings>();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddCookie( conf =>
{
conf.SlidingExpiration = true;
conf.LoginPath = "/account/login";
conf.LogoutPath = "/account/logout";
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
ValidateAudience = false,
ValidateIssuer = false,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidateActor = true
};
});
}

因此,由于 DefaultChallengeScheme 设置为"JwtBearerDefaults.AuthenticationScheme",我假设,如果我想授权使用 cookie 身份验证登录的用户,我应该在该特定的控制器方法中指定 cookie 身份验证方案,如下所示。

[Route("[controller]/[action]")]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public class HomeController : Controller
{
// GET
[HttpGet]
public IActionResult Index()
{
return View();
}
}

但我总是被重定向到登录页面。

我让它工作的唯一方法是当我删除默认身份验证设置时

private static void ConfigureJwt(IConfiguration configuration, IServiceCollection services)
{
var jwtSettings = new JwtSettings();
configuration.Bind(nameof(JwtSettings), jwtSettings);
services.AddSingleton<JwtSettings>();
services.AddAuthentication()
.AddCookie( conf =>
{
conf.SlidingExpiration = true;
conf.LoginPath = "/account/login";
conf.LogoutPath = "/account/logout";
})
.AddJwtBearer("jwt", options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey =
new SymmetricSecurityKey(Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
ValidateAudience = false,
ValidateIssuer = false,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidateActor = true
};
});
}

然后在 Cookie 相关路由上使用正常的 [授权] 属性

[Route("[controller]/[action]")]
[Authorize]
public class HomeController : Controller
{
// GET
[HttpGet]
public IActionResult Index()
{
return View();
}
}

然后在我所有的 API 路由中,我指定了 JWT 的身份验证方案

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet(ApiRoutes.Posts.GetAll)]
public async Task<IActionResult> GetAll()
{
var posts = await _postService.GetAllAsync();
return Ok(posts);
}

所以我的问题是,为什么初始配置不起作用?而且由于我的应用程序主要使用 JWT 身份验证,我希望它成为默认的身份验证方案,并且仅在少数控制器方法中指定 cookie 身份验证方案,因为它很少使用。这可能吗?如果是,我该如何实现?

经过更多的挖掘,我偶然发现了这个线程,它回答了我的问题。

我误解了身份验证在使用标识的 asp.net 核心应用程序中的工作方式。 当您使用Identity对用户进行身份验证和登录时,使用的默认身份验证方案称为"Identity.Applicaiton",而不是"Cookie"。

var result = await _signInManager.PasswordSignInAsync(loginModel.Email, loginModel.Password, true, false);
if (result.Succeeded)
{
return LocalRedirect("/home/index");
}

但是,如果要使用"Cookie"身份验证方案,则必须使用HttpContext.SignInAsync对用户进行身份验证和登录,如下所示,并明确选择"Cookie"作为身份验证方案。

var claims = new[]
{
new Claim("email", user.Email),
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(identity));

最新更新