Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
CarlosRoggan
Product and Topic Expert
Product and Topic Expert
This blog is part of a series of tutorials explaining the usage of SAP Cloud Platform Backend service in detail.
In this post we’re going to try to get a basic understanding about the security mechanism required when calling an API from an external application
It is like an appendix to the previous blog, where we learned the steps to call an API from a REST client tool.
I had promised that nobody would become a security expert
In this blog we'll try to get a little better understanding of what we're doing
But still won't become a security expert. Just learn how Backend service relates to OAuth 2.0 principles.

An API (OData service) created in Backend service, is protected and requires OAuth 2.0  authentication/authorization.
First of all: why OAuth?

Why OAuth at all?


With SAP Cloud Platform Backend service, we’re creating an API (OData service) and exposing it.
Yes, it is a service URL, not an application URL.
As such, it is not meant to be used directly by human users
Human end users want to open a URL of an application with user interaction (Basic Authentication), not a URL which returns a payload of cryptic xml or json.
Thus, direct accessing an API with user credentials is rejected and only access token is accepted.
But…..
Yes, I know that during development time, it is often required to call the service manually.
The cockpit provides a UI which covers most functionality of dealing with OData service
For advanced usage, where an external REST client is really needed, it is possible to deal with the OAuth 2 flow, as explained in a beautiful blog

OAuth  is typically used when servers talk to each other
Note that while servers talk to each other, only tokens are sent around. Tokens have a limited scope and expire after some time, so if the token gets stolen, it is less critical than a password

OK, understood why Backend service doesn’t support Basic Authentication and requires OAuth 2.0

What is it: OAuth 2.0 ?


OAuth is the abbreviation of Open Authorization
OAuth is a protocol which describes a standard way of authorization (and authentication)
It is widely used in the internet, whenever web applications should be equipped with user information from a different server.
In such cases, the web application asks the "different server" to authenticate the user and allow access to the user's information. So the web application doesn't deal with sensitive user credentials. Instead, the "different server" sends a cryptic token to the web application

A very common example is Facebook:
A user opens a web application, which in turn delegates the authentication to Facebook-server. The web application talks to the Facebook server and tells which user should be authenticated and which information and authorizations are necessary. Facebook asks the user to log in. If successful, it sends a token to the web application. Using this token, the web application is allowed to access resources on behalf of the user. The good thing about it: the web app doesn't need to store the password.

OK?

OAuth is a standard for delegation of authorization between web apps

Why 2.0 ?
We're always talking about protocol version 2.0 which is quite different from the previous one.

The protocol is flexible and in case of Backend service it is used in a slightly different way than in the given Facebook example.

The Backend service OAuth Flow


Let’s check the fundamentals of OAuth 2.0 and relate them to the security mechanism in SAP Cloud Platform and Backend service

Participants

OAuth 2.0 describes 4 participants:

- Resource Server
- Authorization Server
- Resource Owner
- Client

Our scenario with Backend service:

In our scenario (see this blog), there's a protected API created in Backend service.
We want to access the API with a REST client tool, to read protected data
To be able to read the protected data, the REST client has to connect to an instance of XSUAA in the SAP Cloud Platform
In any case a permission has to be given to access the API, so we have to give our user credentials of our SAP Cloud Platform user, which is our Trial account user. This user is known to the XSUAA, as such, the XSUAA grants permission to the REST client, to access the API on behalf of us.
In order to access the API, the XSUAA sends a valid access token to the REST client, which in turn can use it to call the API.
























OAuth 2.0 Backend service
Resource Server Backend service API
Resource Owner SAP Cloud Platform user (trial account user)
Authorization Server XSUAA
Client REST client tool (e.g. Postman)


Small recap:
Our REST client tool (Third Party Client) connects to the XSUAA (Authorization server) to get permission to call the API (Resource Server), on behalf of us (Resource Owner).

 

Prerequisite

Before the Authorization Server would be willing to send access tokens to the client, the client must be known to the Authorization Server.
This is achieved with a one-time "registration".

We’ve done that by creating and configuring an XSUAA instance, as described here
While creating and configuring the XSUAA instance in the Cloud Foundry space, we gave some parameters and as a result, we received an identifier for our client (clientid) and a password (clientsecret).
This is described by the OAuth 2.0 spec, however, some parts are quite free and depending on the server and applications

Small recap:
After creating and configuring an XSUAA instance in our cloud account (registration), our REST client can call the OAuth endpoint, along with its own ID (clientid) and password (clientsecret)

Authorization

OAuth is used rather for managing authorization than authentication (although mostly used together).
What does that mean?
Typically, professional applications define their own “Roles”
That way, the application can allow access to parts of the app in a fine granular way.
For example, one special screen of an app can be only opened by a user who has “Admin” role, for all others it doesn't open.
Same can be done with APIs. Backend service supports that by providing a few own roles.
For example, an enterprise service exposes data about customers and their products. While the products are publicly visible, the customers data can only be accessed by users who have a special role for this entity set.
This is the reason why it is necessary that the Authorization Server does know about scopes, roles, role-templates (see xsuaa section below)
With other words, an access token is only valid if it contains information about the required role(s)

Authorization Grant types

What are the requirements to obtain an access token from the authorization server?
Once the client is known to the Authorization Server, it can connect to it and ask for an access token.
Of course, the Resource Owner needs to agree by entering his credentials.
Then the Authorization Server grants access to the client.

OK, but how?
Yes, this process is a bit more complicated.
For this process, OAuth 2.0 defines 4 grant types.
There are differences between them with regard to security level and complexity level, and they are used depending on the scenario.
They can be seen when using tool support in some REST clients (see here), so let’s briefly mention them:

- Authorization Code
- Password Credentials
- Client Credentials
- Implicit

In our scenario, the grant type “Password Credentials” is used. This one is simpler, as it allows to exchange a password for a token in only one step.
This is less secure, but secure enough, because in our scenario everything is in our hands, in our cloud account.
Everything?
I mean, the Resource Server and the Authorization Server and our platform user, they roam around in our Trial account and subaccount. And, actually, also the Client application should be deployed to the same subaccount.
That sounds new
Yes, we have to distinguish between our REST client and our final productive intention:
We create an API with Backend service and afterwards we build a Fiori application (Client) which calls the API.
Both running in the same cloud account.
Also, the Authorization Server (XSUAA instance) is in the same account.
As such, there is trust between the components. And the end users (business users) are most probably maintained in a trusted identity provider.

Note:
Important to note that the typical login-popup is not sent by the Authorizattion Server. In the case of Password Credentials, it is the Client which displays the popup.

However, in our special testing scenario, we’re calling our API with an external REST client which doesn't run in the cloud account. So we have to enter our platform user's password as plain text in the REST client (either as URL parameter or in the request body).

Note:
Don't forget that your password is visible in the REST client tool, so don't share the request with others

How does Grant type “Password Credentials” work?
To get access token by using this grant type, the client has to call the OAuth endpoint of the Authorization Server.
The client sends the following information:

- Who is the Client: clientid, clientsecret
- How to get the token: grant_type=password
- Who is the Resource Owner: username / password of the Resource Owner

In our scenario:
We connect to the oauth endpoint with Basic Authentication, where clientid and clientsecret are entered as credentials. The info about grant_type and the Resource Owner credentials are passed in the URL or in the request body

In a real life scenario, the Resource Owner credentials should be obtained by a popup of the (fiori) application.

Finally, the Authorization Server responds with a payload which contains the access token.
The response contains structured information. There's of course the access_token itself, but also the duration of validity (expires_in) and the type of the token (token_type) and another token which can be used to refresh (refresh_token).
Small recap:
The client application connects to the Authorization Server, using grant type "password", it gives user credentials to obtain a token.

 

Call the Resource Server

What to do with the token?
The final step of the OAuth flow is to use the access token to connect to the Resource Server to request the desired resource.

How to use the token?
Like this:
In the REST client tool, specify authorization type as “Bearer” and enter the token
Technically, it is sent as header with header name "Authorization" and value "Bearer <token>"
The request is sent via HTTPS
In our example:
URL: https://backend-service-api.cfapps.eu10.hana.ondemand.com/odata. . .
Header:
Authorization: Bearer a1Ab2Bb3Cd4De5E…

Why write text "Bearer"?
Because in the header field we have to write the type of the token, in this cases the supported type of token is "Bearer"

Why type "Bearer"?
Because in the response which was sent by the Authorization Server, the type of the access token was written in a property:
"token_type": "bearer"

What is inside the token?
The Resource Server knows how to validate the provided token. If it is valid, the Resource Server sends the requested resources.

What's outside the token?
Strange question. Anyways, the token can be used to call all APIs which require same authentication and authorization. Means, as long as APIs created in Backend service don't require special role or don't restrict the role for some entity sets only, then the token can be used to call all APIs
Furthermore, the Authorization Server sends an "expires" information along with the token. This is supported by the XSUAA and it informs how long the token is valid.
Small recap:
The final step of the OAuth flow is an HTTPS request, sent to the protected API, and the authorization token is passed along with authorization type “Bearer”

The following diagram tries to visualize the (simplified) flow:


About XSUAA


This term has been mentioned many times...
OK, so let's spend a few words about it.

UAA stands for “User Authentication and Authorization”
XSUAA stands for “Extended  Services for UAA”

In order to create an instance of xsuaa service, we have to search for the tile “Authorization and Trust Management” in the service marketplace of our Cloud Foundry space

In our OAuth 2.0 flow, the XSUAA instance acts as “Authorization Server”
More precisely, in the service key info, the URL for the authorization server can be viewed.
To get the endpoint in case of OAuth 2.0, the suffix oauth/token has to be appended.

While creating the XSUAA instance, some parameters have to be given.
In our case it is important to give the following:
{
"xsappname": "myAppName",
"foreign-scope-references": [
"$XSAPPNAME(application,4bf2d51c-1973-470e-a2bd-9053b761c69c,Backend-service).AllAccess"
]
}

What does this mean?
The "xsappname" is a name of your choice which must be unique in the Cloud Foundry space
The "foreign" participant is the Backend service API, which should be called by the client
As mentioned above, the Backend service defines roles (see here).
Whoever wants to call the API, needs valid authentication (cloud user) and authorization (user has a role as defined by Backend service).
More concrete: user needs to have the role "AllAccess"
This requirement is specified in the "foreign-scope-references"
What else?
The variable $XSAPPNAME refers to the property "xsappname" which is given in the same security configuration.
application: this refers to the service-plan chosen when creating the XSUAA instance
4bf...: the tenant id, as we're referring to a subscribed application. This has to be correct, otherwise the token is not valid because the foreign role cannot be found.
Backend-service: the name of referenced foreign application, in our case it is the Backend service
More info?
More info can be found in the SAP Help Portal
Small recap:
When creating an instance of XSUAA service, we have to pass configuration parameters. We specify the role which is required by Backend service.

Summary


In this blog we've learned to understand the authorization mechanism required to call an API of SAP Cloud Platform Backend service.
Finally, we have a better understanding of what we did in the previous blog

Advertisments


Another OAuth 2 blog, explaining the "Authorization Code" grant type

OAuth in real world:

Using REST client: this blog
Using node.js application locally, outside cloud: this blog
Using node.js application deployed to Cloud Foundry: this blog
Using node.js application in Cloud Foundry with service binding to xsuaa: this blog
Using node.js application in Cloud Foundry with service binding to xsuaa and "Authorization Code" (TBD)

The OAuth spec: https://oauth.net/2/
and rfc: https://tools.ietf.org/html/rfc6749
The "Resource Owner Password Credentials" spec

The XSUAA documentation in the SAP Help Portal
Reference of the parameters of xsuaa instance in the SAP Help Portal
Info about xsuaa credentials for remote applications: SAP Help Portal

The Cloud Foundry documentation about UAA is interesting as well
Also this one
And UAA concepts here

About jwt token:
https://jwt.io/
https://tools.ietf.org/html/rfc7519
A tool I've found which visualizes the content of the jwt token: https://devtoolzone.com/decoder/jwt

And finally:
Another great blog, giving more information, e.g. how to troubleshoot tedious error

Security Glossary.