IdentityServer4:为 Client_Credential Granttype 添加自定义默认声明到客户端主体
IdentityServer4: Add Custom default Claim to Client Principal for Client_Credential Granttype
我正在使用 IdentityServer4,我正在尝试在创建令牌时向我的 CLIENT
添加自定义默认声明。如果我使用隐式流程和 IProfileService
如下所示,这是可能的。
public class MyProfileService : IProfileService
{
public MyProfileService()
{
}
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var claims = new List<Claim>
{
new Claim("DemoClaimType", "DemoClaimValue")
};
context.IssuedClaims = claims;
return Task.FromResult(0);
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.FromResult(0);
}
}
在我的创业公司
services.AddIdentityServer()
.AddProfileService<MyProfileService>()
然而,这不适用于我的 client_credential granttype 客户端,因为它看起来 cannot request OpenID scopes in client credentials flow
。事实证明,Iprofileservice 顾名思义适用于 OpenId 范围(如配置文件)有效的 Identity
资源。因为我无法请求具有 client_credential 授权类型 GetProfileDataAsync
的配置文件范围,因此永远不会被调用。
由于我只与客户合作,没有用户,我需要一种方法将声明注入令牌,而不必像下面那样将它们添加到客户对象中
new Client
{
ClientId = "myclient",
ClientName = "My Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = {new Secret("secret".Sha256())},
AllowedScopes = new List<string> {"api"},
AllowOfflineAccess = true,
//I Don't want to do this
Claims = new List<Claim>
{
new Claim("type","value")
}
}
我不想要以上内容,因为我不希望声明成为数据库中 client_claims 的一部分。我需要根据令牌请求即时创建它。我希望我的问题现在更清楚了。
经过一番询问,我终于找到了如何做到这一点。我需要一种在请求令牌时向客户端动态添加声明的方法。
为了做到这一点,我必须扩展 ICustomTokenRequestValidator
,然后将我的 class 包含在 Startup.cs 彻底的依赖注入中
public class DefaultClientClaimsAdder : ICustomTokenRequestValidator
{
public Task ValidateAsync(CustomTokenRequestValidationContext context)
{
context.Result.ValidatedRequest.Client.AlwaysSendClientClaims = true;
context.Result.ValidatedRequest.ClientClaims.Add(new Claim("testtoken","testbody"))
return Task.FromResult(0);
}
}
在Startup.cs
中配置服务
services.AddTransient<ICustomTokenRequestValidator, DefaultClientClaimsAdder>();
或者,您可以使用 ClientStore
向客户端添加新声明。
public class YourClientStore : IClientStore
{
private readonly DbContext _context;
private readonly IMapper _mapper;
public YourClientStore(DbContext context,
IMapper mapper)
{
_context= context;
_mapper = mapper;
}
public Task<Client> FindClientByIdAsync(string clientId)
{
var dbClient = _context.Clients.AsQueryable()
.Where(x => x.ClientId == clientId)
.FirstOrDefault();
var client = _mapper.Map<Client>(dbClient);
if (client != null)
{
client.Claims.Add(new Claim("<your claim name>", "<your claim value>"));
}
return Task.FromResult(client);
}
}
我正在使用 IdentityServer4,我正在尝试在创建令牌时向我的 CLIENT
添加自定义默认声明。如果我使用隐式流程和 IProfileService
如下所示,这是可能的。
public class MyProfileService : IProfileService
{
public MyProfileService()
{
}
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var claims = new List<Claim>
{
new Claim("DemoClaimType", "DemoClaimValue")
};
context.IssuedClaims = claims;
return Task.FromResult(0);
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.FromResult(0);
}
}
在我的创业公司
services.AddIdentityServer()
.AddProfileService<MyProfileService>()
然而,这不适用于我的 client_credential granttype 客户端,因为它看起来 cannot request OpenID scopes in client credentials flow
。事实证明,Iprofileservice 顾名思义适用于 OpenId 范围(如配置文件)有效的 Identity
资源。因为我无法请求具有 client_credential 授权类型 GetProfileDataAsync
的配置文件范围,因此永远不会被调用。
由于我只与客户合作,没有用户,我需要一种方法将声明注入令牌,而不必像下面那样将它们添加到客户对象中
new Client
{
ClientId = "myclient",
ClientName = "My Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = {new Secret("secret".Sha256())},
AllowedScopes = new List<string> {"api"},
AllowOfflineAccess = true,
//I Don't want to do this
Claims = new List<Claim>
{
new Claim("type","value")
}
}
我不想要以上内容,因为我不希望声明成为数据库中 client_claims 的一部分。我需要根据令牌请求即时创建它。我希望我的问题现在更清楚了。
经过一番询问,我终于找到了如何做到这一点。我需要一种在请求令牌时向客户端动态添加声明的方法。
为了做到这一点,我必须扩展 ICustomTokenRequestValidator
,然后将我的 class 包含在 Startup.cs 彻底的依赖注入中
public class DefaultClientClaimsAdder : ICustomTokenRequestValidator
{
public Task ValidateAsync(CustomTokenRequestValidationContext context)
{
context.Result.ValidatedRequest.Client.AlwaysSendClientClaims = true;
context.Result.ValidatedRequest.ClientClaims.Add(new Claim("testtoken","testbody"))
return Task.FromResult(0);
}
}
在Startup.cs
中配置服务 services.AddTransient<ICustomTokenRequestValidator, DefaultClientClaimsAdder>();
或者,您可以使用 ClientStore
向客户端添加新声明。
public class YourClientStore : IClientStore
{
private readonly DbContext _context;
private readonly IMapper _mapper;
public YourClientStore(DbContext context,
IMapper mapper)
{
_context= context;
_mapper = mapper;
}
public Task<Client> FindClientByIdAsync(string clientId)
{
var dbClient = _context.Clients.AsQueryable()
.Where(x => x.ClientId == clientId)
.FirstOrDefault();
var client = _mapper.Map<Client>(dbClient);
if (client != null)
{
client.Claims.Add(new Claim("<your claim name>", "<your claim value>"));
}
return Task.FromResult(client);
}
}