I am using IdentityServer4 and I am trying to add a custom default claim to my CLIENT
when the token is created. This is possible if i use the implicit flow and IProfileService
like shown below.
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);
}
}
And in my startup
services.AddIdentityServer()
.AddProfileService<MyProfileService>()
However this does not work with my client with client_credential granttype since it seems cannot request OpenID scopes in client credentials flow
. It turns out Iprofileservice like the name implies works for Identity
Resources where the OpenId scopes like profile is valid. since am unable to request profile scopes with client_credential grant type GetProfileDataAsync
never gets called.
Since am working only with clients and no users I need a way to inject claims into the token without having to add them to the client object like below
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")
}
}
I do not want the above because i do not want the the claim to be part of the client_claims in the database. I need to create it on the fly on token request. I hope my question is clearer now.
With some inquiries I finally found out how to do this. I needed a way to add claims dynamically to the client when token was requested.
In order to do that I had to extend ICustomTokenRequestValidator
and then include my class in Startup.cs thorough dependency injection
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);
}
}
Configure services in Startup.cs
services.AddTransient<ICustomTokenRequestValidator, DefaultClientClaimsAdder>();