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.1Host: <EID Server>Content-Type: application/x-www-form-urlencodedCache-Control: no-cacheclient_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}