ASP.NET跨项目调用API时Claims用户未认证问题求解
问题描述
在某ASP.NET项目的API Get方法中编写了以下代码:
IEnumerable<Claim> claims = (User.Identity as ClaimsIdentity).Claims; bool isAuthenticated = User.Identity.IsAuthenticated; Claim claimName = claims.FirstOrDefault(c => c.Type.Contains("nonqualified") || string.Equals(c.Type, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"));
通过浏览器直接调用该API时,可正常获取已认证用户的Claims信息;但从另一ASP.NET项目调用此API时,用户显示未认证状态。需要实现跨项目调用时,用户能像浏览器访问一样处于已认证状态。
解决方案
传递认证凭据
浏览器访问时会自动携带认证Cookie(如ASP.NET Identity的Cookie),但跨项目调用不会自动传递。你需要在调用方项目中提取当前用户的认证凭据,并在请求API时附加到请求中:
若使用JWT认证
获取当前用户的JWT令牌,通过Authorization请求头传递:
var token = await HttpContext.GetTokenAsync("access_token"); using var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); var response = await client.GetAsync("https://your-api-domain/api/target-endpoint");
若使用Cookie认证
将当前项目的认证Cookie复制到请求的Cookie容器中:
var cookieContainer = new CookieContainer(); using var handler = new HttpClientHandler { CookieContainer = cookieContainer }; using var client = new HttpClient(handler); // 提取当前上下文的认证Cookie var authCookie = HttpContext.Request.Cookies[".AspNetCore.Identity.Application"]; if (authCookie != null) { cookieContainer.Add(new Uri("https://your-api-domain"), new Cookie(".AspNetCore.Identity.Application", authCookie.Value)); } var response = await client.GetAsync("https://your-api-domain/api/target-endpoint");
统一认证配置
两个ASP.NET项目必须使用完全一致的认证方案和密钥,才能正确识别彼此的凭据:
JWT认证配置
双方的AddJwtBearer需共享相同的Issuer、Audience和签名密钥:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = "your-issuer", ValidateAudience = true, ValidAudience = "your-audience", ValidateLifetime = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-shared-secret-key")) }; });
Cookie认证配置
确保Cookie名称、加密密钥和域名配置一致,可通过共享数据保护密钥存储实现跨项目解密:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Cookie.Name = ".AspNetCore.Identity.Application"; options.Cookie.Domain = ".your-shared-domain.com"; // 跨子域名共享Cookie // 使用共享目录存储数据保护密钥 var dataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"\\shared-server\auth-keys")); options.TicketDataFormat = new TicketDataFormat( dataProtectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", CookieAuthenticationDefaults.AuthenticationScheme, "v2")); });
配置CORS(跨域场景)
若两个项目处于不同域名下,API项目需启用CORS并允许携带凭据:
// Program.cs 中配置CORS builder.Services.AddCors(options => { options.AddPolicy("TrustedCaller", policy => { policy.WithOrigins("https://your-caller-project-domain") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); // 在管道中启用CORS(需放在UseAuthentication之前) app.UseCors("TrustedCaller");
内容的提问来源于stack exchange,提问作者Mohammad Farfour
相关产品推荐
相关产品推荐

