如何创建可供.NET Core API验证消费的跨第三方应用自定义Cookie
实现方案
你可以通过以下两种常用方案实现需求,优先推荐第二种,改造成本最低且兼容性最好:
方案1:改造Cookie认证逻辑,自定义JWT解析
修改Startup.cs中的Cookie认证配置,通过OnValidatePrincipal事件自行解析第三方生成的JWT格式Cookie:
首先需提前安装依赖NuGet包:
Microsoft.AspNetCore.Authentication.Cookies System.IdentityModel.Tokens.Jwt
然后调整认证服务配置:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(opt => { // Cookie参数和第三方生成规则完全对齐 opt.Cookie.Name = "token"; opt.Cookie.Domain = ".my-domain.com"; opt.Cookie.Path = "/"; opt.SlidingExpiration = true; opt.ExpireTimeSpan = TimeSpan.FromDays(7); // 自定义Cookie验证逻辑 opt.Events = new CookieAuthenticationEvents { OnValidatePrincipal = async context => { var cookieToken = context.Request.Cookies["token"]; if (string.IsNullOrEmpty(cookieToken)) { context.RejectPrincipal(); return; } // JWT验证参数必须和第三方生成JWT的参数100%一致 var validationParams = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("双方约定的JWT签名密钥")), ValidateIssuer = false, // 第三方生成JWT时指定了Issuer则设为true,填写对应ValidIssuer ValidateAudience = false, // 第三方生成JWT时指定了Audience则设为true,填写对应ValidAudience ValidateLifetime = true, ClockSkew = TimeSpan.FromMinutes(5) }; try { var tokenHandler = new JwtSecurityTokenHandler(); var principal = tokenHandler.ValidateToken(cookieToken, validationParams, out _); context.Principal = principal; context.Success(); } catch { context.RejectPrincipal(); return; } await Task.CompletedTask; } }; });
同时需确保Configure方法中认证中间件顺序正确:
app.UseRouting(); app.UseAuthentication(); // 必须在UseAuthorization之前 app.UseAuthorization(); app.UseEndpoints(endpoints => { /* 你的端点配置 */ });
方案2:复用原有JWT认证,配置从Cookie读取令牌
该方案改造成本最低,兼容你原有JWT认证逻辑,可同时支持Header传JWT和Cookie传JWT两种场景:
首先安装依赖NuGet包:
Microsoft.AspNetCore.Authentication.JwtBearer
调整认证服务配置:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(opt => { // JWT验证参数和第三方生成规则完全对齐 opt.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("双方约定的JWT签名密钥")), ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ClockSkew = TimeSpan.FromMinutes(5) }; // 配置从Cookie中读取JWT令牌 opt.Events = new JwtBearerEvents { OnMessageReceived = context => { var token = context.Request.Cookies["token"]; if (!string.IsNullOrEmpty(token)) { context.Token = token; } return Task.CompletedTask; } }; });
中间件配置和方案1一致,保持UseAuthentication在UseAuthorization之前即可。
注意事项
- 双方需对齐所有JWT参数:签名密钥、签名算法(默认用HS256即可)、Issuer、Audience、过期时间规则
- Cookie属性需完全对齐:域名、路径、SameSite属性、HttpOnly配置、Secure配置(HTTPS环境下必须开启Secure)
- 跨域场景下需配置CORS允许凭据:
AddCors时需调用AllowCredentials(),前端Angular请求需设置withCredentials: true - 生产环境下JWT签名密钥需存储在环境变量或配置中心,禁止硬编码
内容的提问来源于stack exchange,提问作者Lam Le
相关产品推荐
相关产品推荐

