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: 
In this post I layout the lab setup for the exercises mentioned in my article "How grant-types keep your application secure?". The lab exercises are for examining the influence of configuration parameter grant-type. You may use this as a setup for further exploration. I would be curious to know what you explored. Please share your own experiments in the comments.

Pre-requisite:



  1. Access to a space in SAP BTP Cloud Foundry runtime with 1 GB memory with developer role. If you have completed Get Ready to Develop on SAP BTP | Tutorials for SAP Developers, you are ready.

  2. Terminal (Power Shell/Bash Shell) with following in PATH. Instructions for installation of these are in Configure Essential Local Development Tools | Tutorials for SAP Developers



Lab Setup


Create a new directory and create files with names and content from Appendix 1.

Install the tools. Open a terminal with the directory you created in the previous step as the current directory and execute the commands given below:
> npm init -y
> npm install -D open jwt-decode
> npm install -g httpyac

Login to your Cloud Foundry space. See step 3, 4 of Install the Cloud Foundry Command Line Interface (CLI). These steps are outlined below:
# get the api url for your SAP BTP, Cloud Foundry environment
> cf api <SAP BTP, Cloud Foundry API Endpoint>

# Login using SSO (or skip -sso to use password)
> cf login --sso

Login to SAP BTP command line interface (btp CLI). See step 6 of Get Started with the SAP BTP command line interface (btp CLI) for how to login to SAP BTP command line interface (btp CLI). These are shown below:
> btp login --sso
...
...
OK
...

Build and deploy the application with commands shown below:
> npx mbt build -t .
...
INFO the MTA archive generated at: cf-application_1.0.0.mtar
INFO cleaning temporary files...

> cf deploy cf-application_1.0.0.mtar -f --no-start
...
Process finished.
...

This creates 2 XSUAA service instances. These stand for 2 applications in SAP BTP, Cloud Foundry environment.

  • cf-application-uaa is the XSUAA service instance bound to Business Logic Application

  • cf-approuter-uaa is the XSUAA service instance bound to Application Router.



Typically when deploying a standalone Application Router and a Business Logic Application, they bind to the same XSUAA service instance. In this exercise the Application Router is considered to bind to an independent XSUAA service instance. This is to illustrate the scenario using managed Application Router or another independently developed application.

We need to create keys for these and copy credentials to a file for the tool we use (httpyac) in the exercises.
> cf create-service-key cf-application-uaa key1
..
> cf service-key cf-application-uaa key1
..{
"apiurl": "https://api.authentication.us10.hana.ondemand.com",
"clientid": "sb-cf-approuter!t53187",
"clientsecret": "045c6fe0-4df2-4ff7-BwhlOAVUxlXCqDvUHYW4lSKJyhNLjfXjpTuo=",
"credential-type": "binding-secret",
"identityzone": "provider-2022",
"identityzoneid": "3caxxxxe-4c10-488e-xxxx-2877xxxxf6a6",
"sburl": "https://internal-xsuaa.authentication.us10.hana.ondemand.com",
"subaccountid": "33caxxxxe-4c10-488e-xxxx-2877xxxxf6a6",
"tenantid": "3caxxxxe-4c10-488e-xxxx-2877xxxxf6a6",
"tenantmode": "shared",
"uaadomain": "authentication.us10.hana.ondemand.com",
"url": "https://provider-2022.authentication.us10.hana.ondemand.com",
"verificationkey": "-----BEGIN PUBLIC KEY-----....----END PUBLIC KEY-----",
"xsappname": "cf-approuter!t53187",
"zoneid": "3ca405fe-4c10-488e-a634-2877bdebf6a6"
}

Modify the file .env with content as follows with values obtained in command above. This is for configuring the tool httpYac we use in exercises.

  • blApp_xsappname as xsappname

  • blApp_clientId as clientid

  • blApp_clientSecret as clientsecret

  • blApp_url as url


Sample for values in the file with values from the command above above is:
# file: .env
blApp_xsappname=cf-application!t53187
blApp_clientId=sb-cf-application!t53187
blApp_clientSecret=045c6fe0-4df2-4ff7-BwhlOAVUxlXCqDvUHYW4lSKJyhNLjfXjpTuo=
blApp_url=https://xxx.authentication.xxNN.hana.ondemand.com

blApp_tokenEndpoint={{blApp_url}}/oauth/token
blApp_authorizationEndpoint={{blApp_url}}/oauth/authorize
blApp_scope=" "


Set a shell variable subaccount to value of subaccountid.
#in Powershell
> $subaccount="3caxxxxe-4c10-488e-xxxx-2877xxxxf6a6"
#in bash
> subaccount="3caxxxxe-4c10-488e-xxxx-2877xxxxf6a6"

Repeat the above steps for the second xsuaa instance and update the file .env
> cf create-service-key cf-approuter-uaa key1
..
> cf service-key cf-approuter-uaa key1
..

Update the file .env with the content modified as follows with values for key1 from command above.

  • approuter_xsappname as xsappname

  • approuter_clientId as clientid

  • approuter_clientSecret as clientsecret

  • approuter_url as url



Sample for values in the file with values for key1 above is:
approuter_xsappname=cf-approuter!t53187
approuter_clientId=sb-cf-approuter!t53187
approuter_clientSecret=4e494f95-428a-4829-9a5d-f958gc6fx1Pg_3Hgi9kB3_RvtGsSKQsrs=
approuter_url=https://provider-2022.authentication.xxNN.hana.ondemand.com

approuter_tokenEndpoint={{approuter_url}}/oauth/token
approuter_authorizationEndpoint={{approuter_url}}/oauth/authorize
approuter_scope=" "
approuter_redirectUri=http://localhost:3030/callback

Examine the lab setup


Copy the value of xsappname from the key of cf-application and execute the command shown below.
> btp  get  security/app cf-application!t53187 --subaccount $subaccount
appid: cf-application!t53187
xsappname: cf-application
planName: application
description: <null>
orgId: f2abe5d1-6906-4087-b088-70a886afc711
spaceId: <null>
userName: <null>
planId: ThGdx5loQ6XhvcdY6dLlEXcTgQD7641pDKXJfzwYGLg=
serviceinstanceid: e42921a1-f21d-4720-b1e4-57afa192cc70
masterAppId: <null>
tenant-mode: shared
scopes:
- description: Change grant type Excercise - Scope 1
name: cf-application!t53187.Excercise_User_Scope_1
- description: Change grant type Excercise - Scope 1
name: cf-application!t53187.Excercise_System_Scope_1
foreign-scope-references:
authorities:
- cf-application!t53187.Excercise_System_Scope_1
attributes:
role-templates:
- name: Excercise_Role_1
description: Change grant type Excercise - Role 1
version: JJBej3UQSHJKD7r+IkSTcsQncvwWwMSroxUvLJFrSSM=
scope-references:
- cf-application!t53187.Excercise_User_Scope_1
attribute-references:
appId: cf-application!t53187
capability-types:
instance-authorization:
oauth2-configuration:
token-validity: 0
refresh-token-validity: 0
autoapprove: true
grant-types:
- client_credentials
system-attributes:
allowedproviders: <null>
redirect-uris:
credential-types:
- binding-secret
- x509

Note there are two scopes, one of which is assigned to a role template. The other scope is assigned to authorities. Compare this to the configuration in the file xs-security.json.

Note that only client-credentials is listed for grant-types. Compare this with the entry for cf-application in the file mta.yaml.

Use the tool httpYac to get a token.
> npx httpyac oauth2 --prefix blApp
eyJh.......
....

The output looks like gibberish. But it is not. Lets examine the output.
> npx httpyac oauth2 --prefix blApp | node decode-jwt.js
{
"jti": "5d0c373fd5954b4abce2fe1317d56bb7",
"ext_attr": {
"enhancer": "XSUAA",
"subaccountid": "3caxxxxe-4c10-488e-xxxx-2877xxxxf6a6",
"zdn": "provider-2022"
},
"sub": "sb-cf-application!t53187",
"authorities": [
"uaa.resource",
"cf-application!t53187.Excercise_System_Scope_1"
],
"scope": [
"uaa.resource",
"cf-application!t53187.Excercise_System_Scope_1"
],
"client_id": "sb-cf-application!t53187",
"cid": "sb-cf-application!t53187",
"azp": "sb-cf-application!t53187",
"grant_type": "client_credentials",
"rev_sig": "cccggg",
"iat": 9999999999,
"exp": 9999999999,
"iss": "https://provider-2022.authentication.us10.hana.ondemand.com/oauth/token",
"zid": "3caxxxxe-4c10-488e-xxxx-2877xxxxf6a6",
"aud": [
"uaa",
"cf-application!t53187",
"sb-cf-application!t53187"
]
}

Conclusion



  1. you have setup the lab for exercises

  2. you learnt to examine application configuration using SAP BTP command line interface (btp CLI)

  3. you know how to get tokens using httpyac

  4. you know how to decode and examine JWT with the script in the setup


Next Steps


Proceed with the lab exercises to examine further:

  1. Exercise 1 - grant types for user authorization

  2. Exercise 2 - grant types for basic user propagation

  3. Exercise 3 - grant types for external user propagation


Appendix 1 - Files for Exercises


Make a new directory and copy the content to the files.

Folder Structure


mta.yaml
xs-security.json
.env
decode-jwt.js

└───srv/
package.json

mta.yaml
---
_schema-version: '3.1'
ID: cf-application
version: 1.0.0

modules:
- name: cf-application-srv
type: nodejs
path: srv
parameters:
buildpack: nodejs_buildpack
command: npx http-server
instances: 0 #dont-start the app
memory: 16M
disk-quota: 50M
no-route: true
build-parameters:
builder: custom
commands: []
include: ["package.json"]
requires:
- name: cf-application-uaa

resources:
# this represents a Business Logic Application
- name: cf-application-uaa
type: org.cloudfoundry.managed-service
parameters:
service: xsuaa
service-plan: application
path: ./xs-security.json
config:
xsappname: cf-application
oauth2-configuration:
credential-types:
- binding-secret
- x509
system-attributes: []
grant-types:
- client_credentials

# this represents a managed Application Router
- name: cf-approuter-uaa
type: org.cloudfoundry.managed-service
parameters:
service: xsuaa
service-plan: application
config:
xsappname: cf-approuter
role-templates:
- name: Token_Exchange
description: for User Token exchange
scope-references:
- uaa.user
oauth2-configuration:
credential-types:
- binding-secret
- x509
system-attributes: []
autoapprove: true
grant-types:
- authorization_code

srv/package.json
{
"name": "cf-application-srv",
"version": "1.0.0",
"description": "Change grant-types Exercise - Server",
"keywords": [
"xsuaa",
"cf"
],
"license": "ISC",
"dependencies": {
"http-server": "^14.1.1"
}
}

xs-security.json
{
"scopes": [
{
"name": "$XSAPPNAME.Excercise_User_Scope_1",
"description": "Change grant type Excercise - Scope 1"
},
{
"name": "$XSAPPNAME.Excercise_System_Scope_1",
"description": "Change grant type Excercise - Scope 1"
}
],
"authorities": ["$XSAPPNAME.Excercise_System_Scope_1"],
"role-templates": [
{
"name": "Excercise_Role_1",
"description": "Change grant type Excercise - Role 1",
"scope-references": [
"$XSAPPNAME.Excercise_User_Scope_1"
]
}
],
"role-collections": [
{
"name": "Excercise_Role_Collection_1",
"description": "Change grant type Excercise - Role Collection 1",
"role-template-references": [
"$XSAPPNAME.Excercise_Role_1"
]
}
]
}

.env
## Begin .env

## cf-application-uaa key1
blApp_xsappname=cf-application!tnnnn
blApp_clientId=sb-cf-application!tnnnn
blApp_clientSecret=
blApp_url=https://xxx.authentication.xxNN.hana.ondemand.com

blApp_tokenEndpoint={{blApp_url}}/oauth/token
blApp_authorizationEndpoint={{blApp_url}}/oauth/authorize
blApp_scope=" "


## cf-approuter-uaa key1
approuter_xsappname=cf-approuter!tnnnnn
approuter_clientId=sb-cf-approuter!tnnnn
approuter_clientSecret=
approuter_url=https://xxx.authentication.xxNN.hana.ondemand.com

approuter_tokenEndpoint={{approuter_url}}/oauth/token
approuter_authorizationEndpoint={{approuter_url}}/oauth/authorize
approuter_scope=" "
approuter_redirectUri=http://localhost:3030/callback

## End

decode-jwt.js
  const chunks = [];
process.stdin.on('readable', () => {
let chunk;
while ((chunk = process.stdin.read()) !== null)
chunks.push(chunk)
});


process.stdin.on('end', () => {
const token = chunks.join("");
const decoded = require("jwt-decode")(token);
console.log(decoded)
});