This method of authentication is used to obtain an access token outside the context of a user. With machine-to-machine (M2M) applications, such as CLIs, daemons, or services running on your back-end, the system authenticates and authorizes the app rather than a user. For this scenario, typical authentication schemes like username + password or social logins don't make sense. Instead, M2M apps use the Client Credentials Flow (defined in OAuth 2.0 RFC 6749, section 4.4), in which they pass along their Client ID and their credentials to authenticate themselves and get a token.
The client application can authenticate by sending either client secret or client assertion. Most of the code examples and libraries for this flow cover the first scenario however, NHSD APIs requires the client to pass client assertion.
Obtaining an access token consists of one POST request to the /token
endpoint of the auth server. The body of this
request must be url-encoded with following data:
client_assertion: {jwt}
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
grant_type: "client_credentials"
A JWT token consists of three parts. A header section, body and signature. There are several method of creating and signing JWTs but before diving into that, first we need to discuss what information a client has to provide for header and body section.
The header section contains only one value and that's kid
. The value must be the same as the one you provided during
api registration.
Header:
{
"kid": "kid-value-here"
}
Body:
{
"aud": "",
"exp": 233,
"iss": "",
"jit": ""
}
Despite what library we use to create jwt we need to create a Dictionary
instance to hold both claims and headers data:
var header = new Dictionary<string, string>
{
{ "kid", "TST_Staging" }
};
var claims = new Dictionary<string, string>
{
{ "aud" , "JWT"},
{ "exp", "ES512"},
{ "jti", "TST_Staging" }
};
There are different libraries that can be used to create jwt. This section is about creating and signing JWT and not the authentication process.
Checkout jose-jwt
github page.