如何在Remote Bff Api Endpoint中获取当前用户的用户名和ID?
解决方案
1. 验证BackendApi1的认证配置
由于BackendApi1通过BFF的Remote Endpoint保护,必须确保JWT认证配置正确,能解析BFF转发的用户令牌。在Program.cs中添加或检查以下配置:
builder.Services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = "https://your-identity-service-url"; // 指向你的IdentityService地址 options.TokenValidationParameters = new TokenValidationParameters { ValidateAudience = true, ValidAudience = "backendapi1" // 需与IdentityServer中ApiResource配置的Audience完全一致 }; }); // 务必启用认证与授权中间件 app.UseAuthentication(); app.UseAuthorization();
2. 确保BFF正确转发用户身份信息
FrontendHost作为BFF,需在代理请求到BackendApi1时转发用户声明或访问令牌。若使用YARP做反向代理,添加如下转发逻辑:
builder.Services.AddReverseProxy() .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")) .AddTransforms(context => { context.AddRequestTransform(async transformContext => { var user = transformContext.HttpContext.User; if (user.Identity.IsAuthenticated) { // 方式1:转发访问令牌(推荐) var accessToken = await transformContext.HttpContext.GetTokenAsync("access_token"); transformContext.ProxyRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); // 方式2:直接添加用户声明到请求头(可选) transformContext.ProxyRequest.Headers.Add("X-User-Name", user.FindFirst(ClaimTypes.Name)?.Value); } }); });
同时,BFF的认证配置需确保请求了正确的Scope并保存令牌:
builder.Services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies") .AddOpenIdConnect("oidc", options => { options.Authority = "https://your-identity-service-url"; options.ClientId = "bff-client-id"; options.ClientSecret = "bff-client-secret"; options.ResponseType = "code"; options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("backendapi1"); // 必须包含BackendApi1的ApiScope options.SaveTokens = true; // 保存令牌到Cookie,用于转发 });
3. 在BackendApi1中正确获取用户声明
放弃依赖自定义扩展方法GetUserId(),直接从User.Claims中读取标准声明:
using System.Security.Claims; using Duende.IdentityServer.Models; // 在控制器动作中获取用户名称 var userName = User.FindFirst(ClaimTypes.Name)?.Value; // 或获取用户唯一标识(sub声明) var userId = User.FindFirst(JwtClaimTypes.Subject)?.Value; // 赋值给模型字段 model.CreatedBy = userName ?? userId;
4. 排查声明缺失问题
如果仍无法获取预期声明,可在BackendApi1控制器中打印所有Claims排查:
var allClaims = User.Claims.Select(c => $"{c.Type}: {c.Value}"); foreach (var claim in allClaims) { Console.WriteLine(claim); // 调试时查看输出 }
若缺少name或sub声明,需检查:
- IdentityServer中,BFF客户端是否已授权
openid、profileScope; - BackendApi1的ApiResource配置是否包含这些声明的传递规则;
- 访问令牌的生成逻辑是否包含所需声明。
内容的提问来源于stack exchange,提问作者Osama Mirza
相关产品推荐
相关产品推荐

