This blog is dedicated to Jan, because he asked for it
Hey jpenninkhof , hope you like it 😉
This blog is part of a
series of tutorials explaining the usage of
SAP Cloud Platform Backend service in detail.
Today: How to call APIs from external application like REST client
Quicklinks:
Configure Security
Obtain Token
Call API
Use Tool
Reference
Some things in life are so natural for us that we do it without even realizing it.
For example: breathing. Talk louder when we’re nervous. Use a REST client to call an API. Smile when we’re happy.
And so on.
Similarly, we take for granted that, after creating an API with Backend service, we go to our favorite REST client to use the API.
- Nope -
Doesn’t work:
<error>unauthorized</error>
An Authentication object was not found in the SecurityContext
brrrrrrrrr
But no need to be hopeless: there’s a series of tutorials….
Just follow this tutorial and you’ll be able to do what nature wants you to do.
And don’t worry: you don’t need to be a security expert for following this description.
And don’t worry: after following it, you won’t become a security expert.
If you're interested, please read the
OAuth blog as well
Background
At the current point in time,
SAP Cloud Platform Backend service supports only a very limited set of authorization mechanisms:
- OAuth 2 authentication flow
- nothing else
Reason is the targeted usage by frontend applications rather than human testers.
However, there are reasons why we need to call the APIs also from local REST client: for example, because the cockpit is not powerful enough. This is the case whenever we need to send headers along with a request (e.g. for etag), or if we want to execute batch requests, or if we need to use PUT instead of PATCH
After going through this tutorial you'll be able to easily test all of your APIs with a REST client.
You'll learn that you cannot call your APIs simply providing your user credentials (Basic Authentication isn't supported). Instead, you need to send an
access token. This needs to be fetched once and can be used for some time.
These are the steps we need to do:
Overview of steps:
- Obtain authorization token
OK... I have to admit, this is a too rough overview.
Detailed overview of steps:
- Configure security in Cloud account
1.1. Create xsuaa instance
1.2. Create service key
- Obtain authorization token
- Call API
We need a couple of preparation steps, to be done in our cloud account, before we can request an authorization token: For that purpose there's the service offering "Authorization & Trust Management" in the SAP Cloud Platform.
Please follow this blog to create an service instance with specific parameters for Backend service in customer or trial account:
https://blogs.sap.com/2019/04/29/sap-cloud-platform-backend-service-tutorial-0.5-configure-xsuaa/
Before continuing with the next steps, make sure to view the service key which contains some information required below.
To view the service key:
Go to your BETA-enabled subaccount -> click your space -> Services -> Service Instances
Click your instance -> Service Keys -> select your service key
We take a note of 3 relevant property values (I've marked them in the screenshot above)
Note:
If you don't see some properties, you might need to maximize your browser window, or use a different browser
In my example (slightly modified):
2. Obtain authorization token
Until now, everything was a one-time configuration in the cloud account.
Now we're going to do the actual work:
Call the authorization endpoint to obtain that urgently desired token.
Without that token, we cannot call our API
Note:
This blog is all about that silly token, an endless chain of characters which don't make any sense.
But they have a great value...
The URL
To obtain the token, we have to do a service call to the authentication server.
The url to be called is taken from the <
url> - property mentioned in the previous section.
It is formed as follows:
https://<yourSubAccount>.authentication.<cloud>;
The OAuth endpoint
At the end of above URL, we need to append the endpoint for oauth:
/oauth/token
Putting it together, in my example the endpoint URL looks like this:
https://subaccount.authentication.eu10.hana.ondemand.com/oauth/token
The grant type
Apart from the URL and the OAuth endpoint, there’s some more information required: the "grant type".
We can pass it as query parameters along with the URL
These are the required parameters:
grant_type=password
&username=<yourCloudUserEmail>
&password=<yourCloudPwd>
So, putting all together, the final URL which we call to get the token:
https://...authentication.../oauth/token?grant_type=password&username=your@gmail&password=123
In my example (slightly obfuscated)
https://betasubaccount.authentication.eu10.hana.ondemand.com/oauth/token?grant_type=password&usernam...
Note:
Do I need to note this?
You know anyways very well that all this blog is for testing our APIs with REST client, to learn to build APIs with SAP Cloud Platform Backend service, to learn how to create and use some features (like etag, batch, etc) which cannot be tested with the cockpit.
As such, we can afford to send sensitive user credentials over the net.
In professional environment, you know that you would never send a password as URL parameter, as it would be easy to read it in HTTP logs.
BTW, using the tool support in Postman allows to at least hide the password in the UI. See
appendix
Call the endpoint
To ask for the token, open a browser and pastenthat URL and press ENTER and…
- Nope -
You get a popup:
brrrrrrrrr
That endpoint requires authorization.
What now?
brrrrrrrrr
Yes, I know why you complain and yes, to get the authorization-token, we need another authorization.
Don’t panic, everything will be good.
We do have the necessary credentials: it is in the properties noted above
It is a simple Basic Authentication, where
"user" is the value of the property “
clientid” and
"password" is the value of the property “
clientsecret”
In my example, the (slightly obfuscated) credentials:
The response in the browser body contains a property “
access_token” – and this exactly is what we need.
The value is a long long string with lots of beautiful characters and digits.

Don’t try to remember it or to type it.
Just copy and paste the value without quotation marks
That’s it: now we have the authorization-token.
Finally.
After a few notes, we can start using the token
Note:
You can repeat calling the OAuth endpoint - you’ll always get the same token.
Always?
No, not always. It loses its validity.
You can see it in the property “
expires_in"
In my example:
"expires_in": 43199
It is measured in seconds.
In my example:
43199 would mean 720 minutes, or 12 hours, that's 1 full day, means 2 working days
After expiration, repeat the request to the OAuth endpoint to get a fresh new token.
Note:
I assume your memory has an expiration date, like mine.
So, if you need to refresh your memory, don't hesitate to revisit my blog
You can go directly to the appendix as a reference
Note:
To get the authorization-token, you can leverage your Postman REST client, it has built-in tool support which makes life easier.
See
appendix
Note:
Remember: One of those unavoidable reactions is to smile when happy
I bet you’re smiling, after receiving this token – although it is ugly...
I can even hear you smiling…
Call API
Finally, we can call our lovely API (with REST client).
However, even this step needs a little explanation.
Actually we need 2 (two) explanations:
1. We need to find out the URL (yes, really)
2. We need to know how to specify the authorization
In detail:
1. The API URL
I bet you're wondering, why we need any explanation at all about the URL of the API, as it is there in the cockpit of Backend service.
Yes, yes, the URL is of course taken from your API in Backend service....
However...
there’s really one thing you need to know:
The final URL It is different.
Slightly different.
Your API-URL is shown in the cockpit as follows:
https://subacc-backend-service.cfapps.xx.hana.on...d.com/odatav2/DEFAULT/SRV
However, for external call, the URL has different prefix:
https://backend-service-api.cfapps.xx.hana.on...d.com/odatav2/DEFAULT/SRV
So, instead of
. . .<yourSubAccount>-backend-service. . .
You have to use
. . .backend-service-api. . .
In my example, the final URL to be entered in REST client:
https://backend-service-api.cfapps.eu10.hana.ondemand.com/odatav2/DEFAULT/SRV/Products
2. How to set the authorization
In your REST client, go to "Authorization" section
Specify “Bearer Token” as authorization type
Copy the access token and paste it into the “Token” field
Note:
In case your REST client doesn’t support "Bearer Token" as authorization type:
You can enter the corresponding raw header.
The header entry would look like this (replace aaabbbccc … with your token):
Authorization: Bearer aaabbbccc…
In my example:
So, finally, after composing the URL and setting the authorization as described, you should get a success response after executing the request.
BTW:
All the procedure described in this blog can be used for any supported HTTP verb, like GET, POST, PATCH, DELETE
Note:
Once we have the token, we can call all different APIs of Backend service with it.
However, this statement holds only true as long as the API doesn't require special role
That's it, now we're finally enabled to use our APIs in a more flexible way, calling them with a REST client tool.
Overview of the OAuth 2.0 flow:
Troubleshooting
What to do if you happily deploy everything and try testing and get..... Forbidden ???
See
this blog for a Troubleshooting guide
Summary
In this tutorial we’ve learned how to call an API from an external application, e.g. REST client tool.
This is necessary, e.g. whenever we need to add custom headers (e.g. Etag)
There's a prerequisite: create an instance of "xsuaa" service with service key.
3 properties of the service key are relevant for obtaining an access token
The procedure of externally calling an API requires 2 requests:
1. Call OAuth endpoint to get the access token in the response
2. Call API (with token and modified prefix)
Advertisements
Don't miss the following appendix. It explains how to use the Postman REST client which has built-in tool support for OAuth 2.0 authorization
Once you have your scenario running, you might be interesting in learning a bit more about OAuth, please visit
this blog
In this blog we've discussed the "Password Credentials" grant type. I'd like to recommend also to have a look at
this blog which explains the "Authorization Code" grand type.
In this blog we're using external REST client tool, manually executing service requests.
If you'd like to learn to do that programmatically with node.js, checkout this blog (and little series. Really interesting, you learn about cloud concepts as well, e.g. service binding and programmatically access cloud microservices)
From all REST clients which I’ve tried,
Postman is the only one which provides enough tool support to ease the OAuth authentication for our scenario.
Please follow below description, it makes your life easier.
Why?
You need to build only 1 request
You don't need to deal with headers and params
The authorization details need to be entered only once
It is easy to refresh the token when expired
Proceed as follows:
1. In SAP Cloud Platform, Cloud Foundry Environment, go to your BETA enabled subaccount
2. To view the OAuth relevant information, do the following steps:
- Go to your space with the xsuaa service instance for Backend service
- Go to "Services" -> "Service Instances"
- Click your instance
- Click "Service Keys"
- Select your service key
- take a note of the values of the following properties.
In my example, with slightly obfuscated values:
3. To view your API URL, do the following steps
- Go to your Backend service cockpit and choose the API you wish to call
- copy the URL of the API (OData service)
- change the prefix of the URL
from:
https://yoursubaccount-backend-service.cfapps.xx.hana.ondemand.com/oda...
To
https://backend-service-api.cfapps.xx.hana.ondemand.com/oda...
4. To call your API with Postman, do the following steps:
- Open Postman
- Enter the URL of your API, modified as described above
- Click on the “Authorization” tab
- Click on the TYPE arrow
- Click on OAuth 2.0
- the right area is changed, such that it can deal with access token
- Since we don’t have an access token, we click the button “Get New Access Token”
- A popup is displayed “Get new access token”
Here we enter the required info, based on the properties which we’ve noted above:
Token Name |
any name of your choice, used to distinguish multiple tokens
Leave it empty if you need only one |
Grant Type |
Password Credentials |
Access Token URL |
append /oauth/token to the value of the <url>-property
e.g.
https://subacc.authentication.eu10.hana.ondemand.com/oauth/token |
Username |
here you have to enter the user you use to login into SAP Cloud Platform.
In a trial account, it is your e-mail |
Password |
the password of the user above |
Client ID |
the value of the <clientid> property above,
e.g.
sb-baas_access!55555 |
Client Secret |
the value of the <clientsecret> property above,
e.g.
2skt7w1yCFJVnFdGp06lijlMojc= |
Scope |
not required |
Client Authentication |
Basic Auth header |
Note:
If you try different REST client and grant type "Password" is not supported, then it doesn't help to try e.g. "Client Credentials", it doesn't work, it is a different OAuth flow.
In my example (slightly obfuscated):

- Afterwards click on Request Token
- As a result, you get a popup containing the token (in a list along with other tokens, if you have requested more)
- No need to copy, just scroll down and press “Use Token” to use this token in your main Postman request
- The token is inserted into the "Token"-field and the Postman request is ready to be sent
That’s it, the request is successful.
No need to add more screenshots, so you have to believe it
Summary:
In Postman, create one request to call API (with modified prefix), choose "OAuth 2.0"-Authorization, use the tool-support to set the access token.
Appendix 2: Snippets
For your reference, please find below the relevant copy&paste snippets
Parameters for creation of xsuaa service instance
{
"xsappname": "baas_access",
"tenant-mode": "dedicated",
"description": "Security profile of called application",
"scopes": [
{
"name": "uaa.user",
"description": "UAA"
}
],
"foreign-scope-references": [
"$XSAPPNAME(application,4bf2d51c-1973-470e-a2bd-9053b761c69c,Backend-service).Admin",
"$XSAPPNAME(application,4bf2d51c-1973-470e-a2bd-9053b761c69c,Backend-service).AllAccess"
],
"role-templates": [
{
"name": "Token_Exchange",
"description": "UAA",
"scope-references": [
"uaa.user"
]
}
]
}
Parameters for the token-fetch
<Properties> and their values, to be copied from service key of xsuaa instance.
user credentials for grant type: SAP Cloud Platform user
Request URL:
<url>/oauth/token?grant_type=password&username=xx@yy.com&password=xxx
Authorization:
Choose "Basic Authorization"
Credentials:
user: value of <
clientid> property
pwd: value of <
clientsecret> property
Header:
Content-Type: application/x-www-form-urlencoded
API-call
URL prefix:
https://backend-service-api.....
Authorization: Bearer <yourtoken>
Appendix 3: obtain token with REST client
In above description we used the browser to fetch the authorization token.
It appears to be simpler: less cryptic, less settings, more user interaction
However, for those of you who are interested, let's see the cryptic way of obtaining the token with REST client
It helps to complete the picture
Compose request
There are 2 possibilities:
1. Like above, use GET request and pass the parameters in the URL
2. Alternatively, use POST request and pass the parameters in the request body
Let’s use the second option here
In the REST client:
Enter the URL of the authorization server, as described above in this blog
<url>property with suffix /oauth/token
Choose POST as HTTP verb
In the “Authorization” Tab, choose “Basic Auth” and enter the credentials as described above in this blog:
Username is the
clientid property
Password is the
clientsecret property
Optionally, press “Preview Request”
Go to the "Headers" tab and enter the following header:
Content-Type:application/x-www-form-urlencoded
Note:
How to enter Basic Authentication in raw header section:
In case you need a raw authorization header, you have to use online base64-encoder to encode your password, then enter as follows:
Authorization: Basic c2ItYmFhEzMDIwOjJyaHQ1dzN6Q0JIVW5GZEdwMDhsaWpsVW9q . . . Yz0=
Below screenshot shows the raw headers:
Go to the "Body" tab and enter the OAuth grant type in the request body as described above in this blog.
Example:
grant_type=password&username=my@email.com&password=123
Press “Send” and receive status 200 and the access_token in the response body:
Copy the value of the token without the “
E.g.
eyJhbGciO . . . iJSUzI1NiIsImprdSI6Imh0dHBz . . .Oi8vYn. . . rZW5f
Then proceed calling your API as described above in this blog
Appendix 4: Hiding the password
If you're concerned because in this explanation we've mentioned that the password is visible, as it is sent in plain text over the net:
Let's see 3 possibilities to at least hide your password:
- Easy:
Use the postman tool support, where the password is hidden. See appendix 1
- Less simple:
Use refresh token. First obtain the token as usually, then use the refresh token, such that password is not required anymore. Explained in the next blog's appendix
- More complex:
Use grant type "Authorization Code".
In that case, the password is typed in the login screen of XSUAA, so the password is hidden and never sent in plain text