Skip to Content
Technical Articles

Application Router | SAP Cloud Platform – Cloud Foundry

This blog post series is about developing applications in a multicloud environment.

  1. Cloud Foundry, UAA, and XSUAA
  2. Business Logic App
  3. Service Instance (SAP HANA Cloud)
  4. Application Router
  5. Authentication using XSUAA
  6. Authorization using XSUAA
  7. Application Runtime (appendix)

For the blog post about the SAP Cloud Platform multi-cloud environment, see

Questions? Post as comment.

Useful? Give a like and share on social media. Thanks!

/wp-content/uploads/2016/02/sapnwabline_885687.png

Hands-On Tutorials

Application Router

In this blog series, we explore developing secure applications in a multi-cloud Cloud Foundry environment. This blog is about the application router.

In this blog, we

  • Create a security descriptor file (xs-security.json) for XSUAA
  • Create an XSUAA service instance
  • Create an application router (courtesy of SAP)
  • Update the application manifest for the approuter
  • Validate access to the approuter requires authentication (but not yet for the business app)

Sample Code

As before, we continue with the (slightly modified) sample code from SAP Cloud Platform documentation:

You can download the sample code from repository

Appendix

For more detailed information about the SAP Cloud Platform trial environment, Cloud Foundry buildpacks, dependencies declarations, attributes, Diego cells and more, see the “appendix” blog

/wp-content/uploads/2016/02/sapnwabline_885687.png

Note: SAP HANA eXtended Application Services, in short XS, was introduced in an early release of the SAP HANA 1.0 platform (SPS 05, 2012) to provide built-in application server services, based on the open-source SpiderMonkey Mozilla JavaScript runtime. This architecture was superseded three years later with another SAP implementation this time of the open-source Cloud Foundry environment (SPS 11, 2015), internally referenced at the time as XS 2 and officially named XS Advanced, or XSA.  This Cloud Foundry “/4HANA” implementation is very similar and compatible with the SAP Cloud Platform Cloud Foundry environment except for some branding and functionality specific to the in-memory platform. For example, the CLI is called xs (not cf) but is the same otherwise.

The service broker for SAP HANA was specifically developed for this environment and other services were adapted to the platform like the SAP XSUAA implementation of the Cloud Foundry UAA service, using a file in JSON format named xs-security for its configuration.

Compare

/wp-content/uploads/2016/02/sapnwabline_885687.png

The XSUAA Programming Model

The architecture diagram shows the components involved. The first station a browser (UI/User Agent) request arrives at is the Cloud Foundry Router of the SAP Cloud Foundry environment on the SAP Cloud Platform; this is a platform component managed by SAP. The Cloud Foundry Router forwards the request to the Application Router. This is a component we manager ourselves and we will show you how we construct one in this blog. The Application Router interacts with the UAA and Identity Provider for Security and Session Services using Access Tokens. With these tokens the user request then interacts with the business service in a runtime container.

As an analogy, the user arrives at the hotel (router) and is directed to the reception (application router). The receptionist (UAA) verifies the identity using passport (authentication) and credit card (authorisation). The user gets a room key (token). With this token the user can access the room (business service). 

The SAP Cloud Platform uses SAP Cloud Identity Services as default Identity Provider (IdP) but any SAML 2.0 IdP can be used as alternative.

    As documented

    Authorization Flow

    In case you are interested in the flow, see

    Cheat Sheet

    Confused about the jargon? Here is a refresher.

    • SAML 2.0 (2005) – standard to exchange authentication and authorization data between identity and  service providers (website). XML-based (and a bit clunky as a result). Dates from early 2000s and works great for web browsers but not with apps and mobile devices
    • Oauth 2.0 (2012) – standard for access delegation using tokens. Is an authorization framework with several use cases (the diagram above is just one). It is not a protocol (like SAML)
    • OIDC / OpenID Connect (2014) – provides authentication for OAuth authorization framework.
    • JWT / JSON Web Tokens (2010) – format to exchange tokens in JavaScript Object Notation which is considerably more lightweight when compared to XML. OAuth flows use both SAML (XML) assertions as JWT.

    As a reminder, the concepts were also covered in a previous blog.

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    XSUAA Service Instance

    Security Descriptor | xs-security.json

    Creating a service instance for the XSUAA service is similar to creating other services, like we did for SAP HANA Cloud or an HDI Container for example, although it this case we need to provide a security descriptor file in JSON format named xs-security.

    This file tat defines the details of the authentication methods and authorization types to use for access to your application.

    As documented,

    Although we can add specify scopes (display, edit, delete), attributes, and roles in this file, for now we are going to keep things simple and only reference the (business logi) app name. This should make sense, as the XSUAA service instance needs to know which app(s) it needs to manage the security for.

    {
      "xsappname" : "myapp",
      "tenant-mode":"dedicated"
    }

    Create XSUAA Service Instance

    Command Line

    We then use the security descriptor file to create a service instance of XSUAA using the same create-service command specifying SERVICE, PLAN, and a service instance NAME plus the parameters:

    Valid JSON object containing service-specific configuration parameters, provided either in-line or in a file. For a list of supported configuration parameters, see documentation for the particular service offering.

    As documented in the Cloud Foundry CLI Reference Guide

    # query the marketplace for the xsuaa service
    cf m -s xsuaa
    # create an instance using security descriptor file (choose one)
    cf create-service xsuaa application myxsuaa -c xs-security.json
    cf create-service xsuaa application myxsuaa 
      -c '{"xsappname":"myapp", "tenant-mode":"dedicated"}'
    # query service configuration
    cf service myxsuaa

    SAP Cloud Platform Cockpit

    For one-off situations, we can also use a wizard in the SAP Cloud Platform cockpit to create the instance and either upload the security descriptor file or specify the parameters in JSON format.

    This works exactly the same as in this case the web interface calls the cf create-service command.

    Parameter tenant-mode=dedicated is the default value and can be omitted.

    The SAP Cloud Platform cockpit displays this information at the Cloud Foundry space level: Services > Service Instances

    Here we can also find the information about UAA service plans from the Service Marketplace (again, same cf marketplace commands).

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    Application Router

    SAP Application Router Package

    To enable authentication for our we app we are going to add an application router. 

    As documented:

    The application router is the single point of entry for an application running in the Cloud Foundry environment on SAP Cloud Platform. The application router is used to serve static content, authenticate users, rewrite URLs, and forward or proxy requests to other micro services while propagating user information.

    SAP has made the application router available as Node.js package.

    See also

    Sample Home Page

    For the app router, create an index.html file in web/resources with a link pointing to /myapp. and to /myapp/hana.

    Application Descriptor (package.json)

    Initialise Node (i.e. generate a package.json file) in the web directory as in the previous blog.

    npm init -y

    Add App Router Package

    Install the approuter package in web/node_modules/@sap

    npm i @sap/approuter

    The command adds 248 packages with the usual (deprecated) warnings. Two we caused ourselves by not providing a description and repository field when executing node init.

    Besides approuter, three logging-related packages are added plus xsenv and xssec.

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    Note: Prior to June 2020 we had to specify the SAP NPM Registry (https://npm.sap.com) for packages but this registry is being retired (end of 2020). Contents have been migrated to the public npm registry (https://registry.npmjs.org).

    As documented,

    In case you get error: Not Found – GET https://registry.nodejs.org/@sap%2fapprouter, your environment may still point to the SAP registry, see SAP NPM packages now on npmjs.org.

    npm config delete @sap:registry

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    Add Start Command

    The package.json file contains the start command for the application router and a list of package dependencies. Add the command to start the approuter.

    "start": "node node_modules/@sap/approuter/approuter.js"

    Add Application Router Configuration

    The application router is configured in the xs-app.json file. This file is located, like the application descriptor file package.json in the root of the approuter directory.

    In this configuration file we configure the approuter for authentication, proxying/routing/rewriting. The configuration below configures the approuter to redirect any request for /myapp to a destination with name myapp. By default, every route requires authentication, so the requests to this path will require an authenticated user.

    As documented,

    {
      "routes": [
        {
          "source": "^/myapp/(.*)$",
          "target": "$1",
          "destination": "myapp"
        }
      ]
    }

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    Note: In case you wondered what the ^ and (.*)$ all means, its RegEx. Not very user-friendly but extremely versatile and powerful.

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    App Deployment

    App Manifest

    As with the service instance for SAP HANA Cloud (or the HDI Container to be precise), we need to bind the myxsuaa service instance to our application router (web) and to our business logic app (myapp).

    The destination referenced in the app router configuration file (xs-app.json) is provided here as environment variable. The URL here is set (fixed), so we need to provide a set route as well. Using a random route would not work.

    For more information about routes, see the

    ---
    applications:
    - name: myapp
      path: myapp
      buildpacks:
        - nodejs_buildpack
      routes:
        - route: myapp-101520.cfapps.eu10.hana.ondemand.com
      memory: 128M
      services:
        - hdicontainer-1
        - myxsuaa
    
    - name: approuter
      path: approuter
      buildpacks:
        - nodejs_buildpack
      random-route: true
      memory: 128M
      env:
        destinations: >
          [
            {
              "name":"myapp",
              "url":"https://myapp-101520.cfapps.eu10.hana.ondemand.com",
              "forwardAuthToken": true
            }
          ]
      services:
        - myxsuaa
    

    Command Line

    When we run the command to deploy both apps are build and bound to the services.

    # housekeeping
    cf d[elete] myapp -r -f
    # deploying
    cf push
    # running
    cf a[pps]

    MyApp

    When we query the approuter URL (here a random route) a log on page is returned

    https://approuter-generous-quoll-vr.cfapps.eu10.hana.ondemand.com

    The configured (default) identity provider is SAP ID Services and the Node approuter app redirects to

    https://accounts.sap.com/saml2/idp/sso

    Should we provide incorrect authorization information, XSUAA displays a (default) error page.

    When the log on succeeds we are redirected back to the approuter for the home page (index.html). The business logic was covered in the previous blog:

    • The URL /myapp points to the / and function res.send is executed.
    • The URL /myapp/hana points to /hana and function req.de.exec is executed

      <a href="/myapp/">myapp</a>
      <a href="/myapp/hana">myapp/hana</a>
    

    Note that we remain connected to the app router (URL). We are not redirected to the business app.

    Note also that as we have not made any changes regarding restrictions, direct access to the myapp URLs also continue to work. We will address this in the next blog.

    SAP Cloud Platform Cockpit

    The Service Instances menu shows the service instances we created plus their bindings.

    When we select the approuter, the destination is listed as user-provided environment variable.

    The service bindings provide the information (e.g. clientid, clientsecret, and certificate) for the apps to communicate with each other.

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    Please Proceed

    We now have covered the out-of-the-box authentication provided by the (SAP) Application Router. In the next blog we explore how we can adapt our Business Logic App to provide integrated authentication.

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    Share and Connect

    Enjoyed the blog? Post a comment, share on social media, and/or give a like. Thanks!

    If you would like to receive updates, connect with me on

    Best,

    Denys van Kempen

    /wp-content/uploads/2016/02/sapnwabline_885687.png

    1 Comment
    You must be Logged on to comment or reply to a post.
    • This is a really detailed body of work, Denys.  Thanks for such an epic article. There’s a lot you point out in this that I look forward to trying first-hand.