如何根据客户端需求发放用户声明?(Duende Identity Server 5/4)
实现按客户端需求动态发放phone_number/email声明(Duende IS5/IS4)
一、数据库端配置客户端偏好
不用修改核心表结构,直接利用Identity Server内置的Client.Properties字段(键值对类型)存储客户端的声明偏好:
- 若客户端需要
phone_number声明,添加键值对:Key = "PreferredClaim",Value = "phone_number" - 若客户端需要
email声明,添加键值对:Key = "PreferredClaim",Value = "email"
如果用SQL直接配置(以SQL Server为例):
UPDATE Clients SET Properties = JSON_MODIFY(Properties, '$.PreferredClaim', 'phone_number') WHERE ClientId = '你的客户端ID';
也可以在Identity Server管理界面(如AdminUI)中找到对应客户端,在Properties区域手动添加上述键值对。
二、在ProfileService中校验并添加声明
在自定义ProfileService的GetProfileDataAsync方法里,读取客户端偏好并动态生成声明:
public async Task GetProfileDataAsync(ProfileDataRequestContext context) { var userId = context.Subject.GetSubjectId(); var user = await _userManager.FindByIdAsync(userId); if (user == null) throw new ArgumentException("用户不存在"); // 获取当前客户端指定的偏好声明类型 context.Client.Properties.TryGetValue("PreferredClaim", out var preferredClaim); var claims = new List<Claim>(); // 按偏好添加对应声明,二者择一 switch (preferredClaim?.ToLower()) { case "phone_number": if (!string.IsNullOrEmpty(user.PhoneNumber)) { claims.Add(new Claim(JwtClaimTypes.PhoneNumber, user.PhoneNumber)); claims.Add(new Claim(JwtClaimTypes.PhoneNumberVerified, user.PhoneNumberConfirmed.ToString().ToLower())); } break; case "email": if (!string.IsNullOrEmpty(user.Email)) { claims.Add(new Claim(JwtClaimTypes.Email, user.Email)); claims.Add(new Claim(JwtClaimTypes.EmailVerified, user.EmailConfirmed.ToString().ToLower())); } break; default: // 未配置偏好时的默认逻辑,比如默认添加email if (!string.IsNullOrEmpty(user.Email)) { claims.Add(new Claim(JwtClaimTypes.Email, user.Email)); } break; } context.IssuedClaims.AddRange(claims); }
三、额外注意事项
- 确保客户端的
AllowedScopes包含对应权限:需要phone_number的客户端要加入phonescope,需要email的客户端要加入emailscope,同时必须包含openidscope。 - 若用户未填写对应联系方式(手机号/邮箱),可根据业务逻辑选择跳过声明添加或抛出提示,建议代码中保留非空校验。
- 如需严格管控偏好配置,可在管理界面将偏好设置为下拉选择项,避免手动输入错误值。
内容的提问来源于stack exchange,提问作者Yoda
相关产品推荐
相关产品推荐

