OAuth Client Grant Types – authorization_code & password
Hi there,
After following the most excellent SAP S/4HANA Cloud SDK Overview tutorial I wanted to learn more about configuring OAuth grants for different usage scenarios.
I’ll share with you how to get both Authorization Code Grant and Resource Owner Password Credentials Grant configured for access to the backend microservice.
As a prerequisite I’ll assume you have successfully completed the SAP S/4HANA Cloud SDK Overview tutorial to Step 7. If you have you’ll get a 401 code with the following warning when accessing the backend microservice API
{
"error": "unauthorized",
"error_description": "An Authentication object was not found in the SecurityContext"
}
To get the grants below working you will need the application name, clientid, client secret and authorization service url (XSUAA). All can be found in the backend microservices service binding to the xsuaa service.
Authorization Code Grant
As per Cloud Foundry doco:
In the authorization code grant flow, the user is directed to a page on the UAA where they grant approvals to the client (Step 1); After the user approves the requested scopes, they are redirected back to the client application with an authorization code in the URL parameters (Step 2); The client application may then exchange the authorization code with UAA to obtain an access token (Step 3). Client application use the access token to view the restricted resource (Step 4).
So, in the authorization code grant flow the user is prompted to grant approvals by providing valid credentials. You might have seen this type of flow when one website wants you to allow it to use the APIs of another web site e.g. a recruitment agency requests access to your LinkedIn account to read your employment history.
Step 1 – Grant approvals
The Cloud Foundry UAA doco specifies the parameters. Adjust below url accordingly.
https://xxxtrial.authentication.eu10.hana.ondemand.com/oauth/authorize?response_type=code&client_id=xxxclientidxxx&scope=firstappxxx.Display&redirect_uri=https://firstAppxxx.cfapps.eu10.hana.ondemand.com/hello
Note – the scope is specified in the Tutorial Step 7 as the applicationName.Display. And as we have seen the application name was in the service bindings. Just add them together in this case.
You will be redirected to the uaa login page. Complete and proceed.
Step 2 – Get the authorization code
Upon submission of the login page you will be redirect to the redirect url parameter specified. Now you’ll see the authorization code as a parameter. Copy the auth code.
Step 3 – Exchange authorization code for an access token
I’ll use Postman to simulate how a client might exchange the auth code for an access token. The Cloud Found UAA doco specifies the parameters for the /oauth/token request. My url is:
https://xxxtrial.authentication.eu10.hana.ondemand.com/oauth/token
Request authorization
Add the client id and client secret obtained earlier.
Request headers
This is what the request headers looks like. Authorization header is added by Postman.
Request body
- grant_type – the type of authentication being used to obtain the token, in this case authorization_code
- code – authorization code obtained in step 2 above (the observant reader will notice the screenshot codes doesn’t match, I know, just ignore and follow instructions)
- redirect_uri – restricted resource which in this case is the backend microservice.
Response
Upon successful post you will get the access_token in the response body. Also, you will get other information,e.g. refresh_token, to generate a new access token once the current one expires. You don’t want to prompt the user for access every time! Keep this info safe.
Step 4 – Use the access token to get access to restricted resource
The Authorization header contains the access token as “Bearer Access_Token“. We will use this to get access to the backend microservice.
You will now have access to the backend microservice.
Resource Owner Password Credentials Grant
As per Cloud Foundry doco:
The name “password” refers to the Resource Owner Password Grant type. The user, who trusts the security of the application, provides their username and password to the client app which may then use them to obtain an
access_token
(Step 1). Client app use the access token to view the restricted resource.
Can be used in situations where the client is not running in a browser e.g. a mobile application. Note the username and password does not need to be saved. The password grant will specify a refresh_token that can be used to generate an access_token if the current access token expires.
Step 1 – Get the access token
I’ll use Postman to simulate how a client might use the user credentials to get the access token. HTTP post to the authorization service (XSUAA)
https://xxxtrial.authentication.eu10.hana.ondemand.com/oauth/token
Request authorization
Add the client id and client secret as basic authentication to the request.
Request headers
Authorization header is added by Postman.
Request body
The Cloud Foundry UAA doco specifies the parameters.
- grant_type – the type of authentication being used to obtain the token, in this case password
- username – the user’s username
- password – the user’s password
Response
Upon successful post you will get the access_token in the response body. Also, you will be other information,e.g. refresh_token, to generate a new access token once the current one expires. You don’t want to persist the user credentials! Keep this info safe.
Use this acces_token to get access to the backend microservice.
Summary
And that is how you can use the xsuaa service to implement various oauth flows. Hope you find it helpful.
Dear Nic Botha,
I tried the way for Owner Password Credentials Grant,
I passed the “username and password” which I is created in IDP service.
but I get a error response when using Post Man to fetch the token.
{
“error”: “unauthorized”,
“error_description”: “Bad credentials”
}
is it correct to pass the “username and password” which is in IDP?
Hi Eric,
As documented in SAP note: https://launchpad.support.sap.com/#/notes/2766354, custom IdP, including IAS is not yet supported in "password" grant_type.
Regards,
Binson
Hey Binson,
a question here, if you use a custom IDP (in my case Successfactors) then how to you obtain a token at all? I tried client_credetials etc. but nothing works. How are Microservice supposed to communicate with each other if I can't request a token in a specific scope?
Thanks for your help
Regards
Mathias
Hi,
What is the alternative for custom IDPs.
We can not share the client secret so is there any other method to get the token providing username and password.
Thanks,
Rajdeep Bhuva
Thanks for sharing this Nic Botha
Can you elaborate on how you would then use the refresh_token to generate a new token?
Hi,
nice Blog. Helped a lot !
I wonder if there is a way to generate an access token that does not expire or at least lasts longer than the 12 h that I get now.
Please advise.
Hi Eric Tang
The username and password are our d-user and password? Because in SCP I am using my sap email id in trust configuration of SAPID Services identity provider.
and for the above blog, I am getting this error
{
"error": "invalid_request",
"error_description": "Missing grant type"
}
even though I have added grant_type: Password Credentials.
Thanks,
Jalpa Patel
you should work with x-www-form-urlencoded rather than form-data which has the problem you mentioned.
Hi guys
is possible to disable some grant type? for example I need force only password type, not client_credentials.
Hi, great blog really very useful.
How to use “grant_type” in Mobile Service (SCP CloudFoundry)? There isn't a field for this value in "Mobile Connectivity"-><destination>->"Security" section
By default you can authenticate using bearer token
https://docs.cloudfoundry.org/api/uaa/version/4.19.0/index.html#with-authorization
grant_type=client_credentials
using the bearer token to call your service