Requesting PoP Tokens
Remark this is beta documentation.
PoP access tokens can be requested as part of an authorization code or refresh token flow.
The specifications allow a number of variations, but IdentityServer right now only supports client generated asymmetric proof keys.
In a nutshell this works like this:
- client generates an asymmetric key pair (e.g. RSA or EC)
- client sends the public key part to identityserver along with the token request
- identityserver will embed the key into the access token (inside the cnf claim)
- client will use the private key to sign the HTTP requests, the resource server will use the public key from the access token to verify the signatures
Generating a key pair
// create key pair
var p = RsaPublicKeyJwk.CreateProvider();
var key = p.ExportParameters(false);
// package public key part as a JWK
var jwk = RsaPublicKeyJwk.CreateJwk(key);
var jwk64 = RsaPublicKeyJwk.CreateJwkString(jwk);
Requesting a PoP token
First request a token via authorization code flow - then when exchanging the token, send the public key along.
var tokenClient = new TokenClient(
IdentityServerPipeline.TokenEndpoint,
ClientId,
ClientSecret);
var tokenResponse = await tokenClient.RequestAuthorizationCodePopAsync(
authResponse.Code,
ClientRedirectUri,
key: jwk64,
algorithm: jwk.alg);
Sending the token
Our PoP client library takes care of signing the outgoing HTTP requests
// configure signing details
var signature = new RS256Signature(p);
var signingOptions = new RequestSigningOptions();
var signingHandler = new HttpSigningMessageHandler(signature, signingOptions);
// set pop token
var client = new HttpClient(signingHandler);
client.SetToken("PoP", tokenResponse.AccessToken);
// call API
var apiResponse = await client.GetAsync(WebApiPipeline.Endpoint);
The full source code can be found here. Also a sample can be found here.