如何强制OpenIDDict始终将单个amr声明值以数组形式输出?
解决OpenIDDict输出amr声明为非数组格式的问题
思路1:在OpenIDDict服务端强制转换amr格式
如果你的OpenIDDict是作为.NET服务运行的,可以通过自定义**声明转换器(Claims Transformer)**拦截并修正amr字段:
public class AmrArrayTransformer : IClaimsTransformer { public Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context) { var amrClaim = context.Principal.FindFirst("amr"); if (amrClaim == null) return Task.FromResult(context.Principal); // 检查当前值是否为数组,不是则转为数组格式 if (!amrClaim.Value.StartsWith("[")) { context.Principal.RemoveClaim(amrClaim); // 用JSON数组格式重新添加声明 context.Principal.AddClaim(new Claim( "amr", JsonSerializer.Serialize(new[] { amrClaim.Value }), JsonClaimValueTypes.JsonArray )); } return Task.FromResult(context.Principal); } }
在Startup.cs中注册该转换器:
services.AddScoped<IClaimsTransformer, AmrArrayTransformer>();
思路2:在Python Authlib端处理解析后的claims
如果是在Python服务中通过Authlib接收OpenIDDict返回的Token,可在解析后统一修正amr格式:
from authlib.jose import jwt def parse_oidc_token(token, public_key): # 解析并验证Token claims = jwt.decode(token, public_key) claims.validate() # 强制amr为数组格式 amr = claims.get('amr') if amr is not None: if isinstance(amr, str): claims['amr'] = [amr] return claims
思路3:修改OpenIDDict的Token生成逻辑
直接在OpenIDDict生成ID Token的环节干预,监听TokenGenerating事件修改claims中的amr字段:
services.AddOpenIddict() .AddServer(options => { options.AddEventHandler<OpenIddictServerEvents.TokenGenerating>(context => { var amr = context.Principal.FindFirst("amr")?.Value; if (!string.IsNullOrEmpty(amr) && !amr.StartsWith("[")) { // 替换原有的amr声明为数组 context.Principal.RemoveClaim(context.Principal.FindFirst("amr")); context.Principal.AddClaim(new Claim("amr", JsonSerializer.Serialize(new[] { amr }), JsonClaimValueTypes.JsonArray)); } return default; }); });
内容的提问来源于stack exchange,提问作者TGlatzer
相关产品推荐
相关产品推荐

