asp.net core 3.1如何实现cookie和jwt两种认证方案共存?
摘要:内容 在我的项目中有mvc controller(view 和 razor Page)同时也有webapi,那么就需要网站同时支持2种认证方式,web页面的需要传统的cookie认证,webapi则需要使用jwt认证方式,两种默认情况下不能
内容
在我的项目中有mvc controller(view 和 razor Page)同时也有webapi,那么就需要网站同时支持2种认证方式,web页面的需要传统的cookie认证,webapi则需要使用jwt认证方式,两种默认情况下不能共存,一旦开启了jwt认证,cookie的登录界面都无法使用,原因是jwt是验证http head "Authorization" 这属性.所以连login页面都无法打开.
解决方案
实现web通过login页面登录,webapi 使用jwt方式获取认证,支持refreshtoken更新过期token,本质上背后都使用cookie认证的方式,所以这样的结果是直接导致token没用,认证不是通过token唯一的作用就剩下refreshtoken了
通过nuget 安装组件包
Microsoft.AspNetCore.Authentication.JwtBearer
下面是具体配置文件内容
//Jwt Authentication
services.AddAuthentication(opts =>
{
//opts.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
//opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
//这里是关键,添加一个Policy来根据http head属性或是/api来确认使用cookie还是jwt chema
.AddPolicyScheme(settings.App, "Bearer or Jwt", options =>
{
options.ForwardDefaultSelector = context =>
{
var bearerAuth = context.Request.Headers["Authorization"].FirstOrDefault()?.StartsWith("Bearer ") ?? false;
// You could also check for the actual path here if that's your requirement:
// eg: if (context.HttpContext.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCulture))
if (bearerAuth)
return JwtBearerDefaults.AuthenticationScheme;
else
return CookieAuthenticationDefaults.AuthenticationScheme;
};
})
//这里和传统的cookie认证一致 .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/Identity/Account/Login";
options.LogoutPath = "/Identity/Account/Logout";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.Cookie.Name = "CustomerPortal.Identity";
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromSeconds(10); //Account.Login overrides this default value
})
.AddJwtBearer(x =>
{
x.RequireHttpsMe
