OAuth 2.0 Client Certificate Grant
The Client Certificate Grant is used to send a signed SAML assertion, along with the Client ID and Client Secret of the OAuth application you registered in EmpowerID to the EmpowerID token endpoint in exchange for an access token, a refresh token, and an ID token (when scope=openid). This article describes how to use this grant in your applications.
You can download sample .NET framework code at https://dl1.empowerid.com/files/OAuthTestSampleCode.zip.
Client Certificate Grant
-
Initiate a request to the EmpowerID Token endpoint,
https://<EID Server>/oauth/v2/tokenPOST /oauth/v2/token HTTP/1.1
Host: <EID Server>
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
client_id={The Client ID of the OAuth app you registered in EmpowerID}
&client_secret={The Client Secret of the OAuth app you registered in EmpowerID}
&grant_type=urn:ietf:params:oauth:grant-type:certificate-bearer
&assertion=xxxxxxxxxxxxxxxxxx
&scope=openidHeader Parameter Required/Optional Description Content-Typerequired Must be application/x-www-form-urlencoded.Post Body Parameter Required/Optional Description client_idrequired Must be the EmpowerID OAuth application client identifier. client_secretrequired Must be the EmpowerID OAuth application client secret. grant_typerequired Must be urn:ietf:params:oauth:grant-type:certificate-bearerscoperequired A space-separated list of strings that the user consents to. Values include openidfor OpenID Connect flow.assertionrequired Must be SAML assertion string. Please refer to Generate SAML Assertion section below. -
Returns access token and refresh token (optionally ID token) in the response
{
"access_token": "xxxxxxxxxxxxxxxxxxxxxx",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "xxxxxxxxxxxxxxxxxxxxxx",
"id_token": "xxxxxxxxxxxxxxxxxxxxxx",
"id": "xxxxxxxxxxxxxxxxxxxxxx"
}
Generate SAML Assertion
The SAML assertion should follow the below format and be signed with the signing certificate and converted to Base64 string - base64(sign(<SAML Assertion>)).
When using the below SAML assertion, do the following:
-
For
<saml:Issuer>, replace<EmpowerID OAuth Application ClientID>with the actual ClientID of the EmpowerID OAuth Application -
For
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">, replace<Signing Certificate Thumbprint>with the thumbprint of your signing certificate -
The value for
<saml:AuthnContextClassRef>is a constant and must not be changed.<?xml version="1.0"?>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_2f665070-6a35-4899-a113-234d8ffa7676" IssueInstant="2019-09-20T14:00:13.357Z">
<saml:Issuer><EmpowerID OAuth Application ClientID></saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#_2f665070-6a35-4899-a113-234d8ffa7676">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<InclusiveNamespaces xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="#default saml ds xs xsi"/>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>dlp3Cn+. . .. . .. .. .. W5hXA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>Q+Ftb+nyCD0Ey9qQ. . .... . . OsFtxAfopOcaprm4=</SignatureValue>
</Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"><Signing Certificate Thumbprint></saml:NameID>
</saml:Subject>
<saml:Conditions/>
<saml:AuthnStatement AuthnInstant="2019-09-20T14:00:13.638Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:X509</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
Client Certificate Grant using .NET Client Library
-
Initialize
ClientSettingsby passing theclient_id,client_secret,redirect_uri,token_endpoint,authorization_endpoint,tokeninfo_endpointanduserinfo_endpoint. Also initialize a newClientCertificateGrantby passing the clientSettings model.var clientSettings = new ClientSettings(
"client_id",
"client_secret",
"redirect_uri",
"https://<EID Server>/oauth/v2/token",
"https://<EID Server>/oauth/v2/ui/authorize",
"https://<EID Server>/oauth/v2/tokeninfo",
"https://<EID Server>/oauth/v2/userinfo");
var handler = new ClientCertificateGrant (clientSettings); -
Call the
GetAccessToken()method to retrieve theaccess_token,refresh_token, and other token related information.AccessTokenResponseModel responseModel = null;
String certificateThumbprint= "xxxxxxxxxxxxxxxxxxxxx";
try
{
var signingCert = handler.GetSigningCertificate(certificateThumbprint);
responseModel = handler.GetAccessToken<AccessTokenResponseModel>
(RequestMethod.POST,
ParameterFormat.Json,
signingCert);
}
catch (Exception e)
{
//Handle error
}