前言
此文章是用来记录我遇到问题时,其解决方法、个人想法,如果有误,希望可以指出。
问题
本人在学习IdentityServer4文档中的oidc(使用OpenID Connect添加身份验证)的时候,账号密码验证完了之后,想要向Cookie添加自定义的Claim的时候,却发现添加不了(客户端没有看到我自定义的Claim)。
//这里只展示自定义Claim添加Cookie相关得代码
//自定义Claim
Claim[] claims = new Claim[]
{
new Claim(ClaimTypes.Name, user.Nickname),
new Claim(ClaimTypes.OtherPhone,user.Phone)
};
//添加到Cookie
await HttpContext.SignInAsync(viewModel.UserName, claims);
上图是客户端展示HttpContext.User.Claims所有属性时的图,可以看到没有我自定义的Claim
个人想法
在IdentityServer4的使用《OpenID Connect添加身份验证》文档结尾中发现一段话
It is also noteworthy, that the retrieval of claims for tokens is an extensibility point - IProfileService
大致意思是IProfileService对令牌声明的检索是一个可扩展性点 ,然后百度了一下,看了晓晨大大的文章和若邪的文章(最下面有链接)之后,顿时茅舍顿开,我们在自定义Claim的时候,单单将Claim作为SignAsync的参数添加,还不够,还要实现IProfileService接口
解决方法
IProfileService是专门用来装载我们需要的Claim信息的,在进行SignAsync操作之后,IdentityServer4会在DefaultClaimsService类中调用IProfileService的GetProfileDataAsync方法,而这个方法就可以添加我们的Claim。
服务端实现IProfileService接口
//这里实现的还不够完整,还可以依赖注入Logger来进行日志记录
public class ImplicitProfileService : IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
//获取IdentityServer给我们定义的Cliams和我们在SignAsync添加的Claims
var claims = context.Subject.Claims.ToList();
context.IssuedClaims = claims;
return Task.CompletedTask;
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.CompletedTask;
}
}
然后我们在服务端的Startup类中添加我们实现的类
services.AddIdentityServer(options =>
{
options.UserInteraction.LoginUrl = "/Account/Login";
})
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(config.GetApiResource())
.AddInMemoryClients(config.GetClients())
.AddInMemoryIdentityResources(config.GetIdentityResources())
.AddProfileService<ImplicitProfileService>();
添加之后再重新访问,会发现客户端有我们自定义的Claim了
参考
晓晨Master:https://www.cnblogs.com/stulzq/p/8726002.html
若邪:https://www.cnblogs.com/jaycewu/p/7791102.html