Secrets

In certain situations, clients need to authenticate with identityserver, e.g.

  • confidential applications (aka clients) requesting tokens at the token endpoint
  • APIs (aka resource scopes) validating reference tokens at the introspection endpoint

For that purpose you can assign a list of secrets to a Client or a Scope.

Secret parsing and validation is an extensibility point in identityserver, out of the box it supports shared secrets (stored hashed or plaintext - but defaults to hashed) as well as transmitting the shared secret via a basic authentication header or the POST body.

Creating a shared secret

The following code sets up a hashed shared secret:

var secret = new Secret("secret".Sha256());

This secret can now be assigned to either a Client or a Scope. Notice that both do not only support a single secret, but multiple. This is useful for secret rollover and rotation:

var client = new Client
{
    ClientId = "client",
    ClientSecrets = new List<Secret> { secret },

    AllowedGrantTypes = GrantTypes.ClientCredentials,
    AllowedScopes = new List<string>
    {
        "api1", "api2"
    }
};

In fact you can also assign a description and an expiration date to a secret. The description will be used for logging, and the expiration date for enforcing a secret lifetime:

var secret = new Secret(
    "secret".Sha256(),
    "2016 secret",
    new DateTime(2016, 12, 31));

Authentication using a shared secret

You can either send the client id/secret combination as part of the POST body:

POST /connect/token

client_id=client1&
client_secret=secret&
...

..or as a basic authentication header:

POST /connect/token

Authorization: Basic xxxxx

...

You can manually create a basic authentication header using the following C# code:

var credentials = string.Format("{0}:{1}", clientId, clientSecret);
var headerValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", headerValue);

The IdentityModel library has helper classes called TokenClient and IntrospectionClient that encapsulate both authentication and protocol messages.