To get an access_token via clientcredential flow, you call /connect/token like this
curl -X POST https://<identityserver>/connect/token
-H 'Content-Type: application/x-www-form-urlencoded'
-d 'grant_type=client_credentials&scope=myscope1'
It doesn't seem like I could customise /connect/token to take custom parameters? I would like to take the custom values from the api and add them to my custom claims via ICustomTokenRequestValidator (https://stackoverflow.com/a/43930786/103264)
You can customize your call using acr_values
parameter. For instance, below we take a tenantId value as a parameter, validate it and put into the token as a claim.
The call looks like:
curl -d "grant_type=client_credentials&client_id=the-svc-client&client_secret=the-secret&acr_values=tenant:DevStable" https://login.my.site/connect/token
And the vlidator (partially copy&pasted from AuthRequestValidator):
public Task ValidateAsync(CustomTokenRequestValidationContext context)
{
var request = context.Result.ValidatedRequest;
if (request.GrantType == OidcConstants.GrantTypes.ClientCredentials)
{
//////////////////////////////////////////////////////////
// check acr_values
//////////////////////////////////////////////////////////
var acrValues = request.Raw.Get(OidcConstants.AuthorizeRequest.AcrValues);
if (acrValues.IsPresent())
{
if (acrValues.Length > context.Result.ValidatedRequest.Options
.InputLengthRestrictions.AcrValues)
{
_logger.LogError("Acr values too long", request);
context.Result.Error = "Acr values too long";
context.Result.ErrorDescription = "Invalid acr_values";
context.Result.IsError = true;
return Task.CompletedTask;
}
var acr = acrValues.FromSpaceSeparatedString().Distinct().ToList();
//////////////////////////////////////////////////////////
// check custom acr_values: tenant
//////////////////////////////////////////////////////////
string tenant = acr.FirstOrDefault(x => x.StartsWith(nameof(tenant)));
tenant = tenant?.Substring(nameof(tenant).Length+1);
if (!tenant.IsNullOrEmpty())
{
var tenantInfo = _tenantService.GetTenantInfoAsync(tenant).Result;
// if tenant is present in request but not in the list, raise error!
if (tenantInfo == null)
{
_logger.LogError("Requested tenant not found", request);
context.Result.Error = "Requested tenant not found";
context.Result.ErrorDescription = "Invalid tenant";
context.Result.IsError = true;
}
context.Result.ValidatedRequest.ClientClaims.Add(
new Claim(Constants.TenantIdClaimType, tenant));
}
}
}
return Task.CompletedTask;
}