cancel
Showing results for 
Search instead for 
Did you mean: 

Cloud Foundry Portal HTML5 Apps Repo Authorization

former_member194549
Contributor
0 Kudos

Hello everybody,

I create a Node.js application on Cloud Foundry with an HTML5 application that is stored in the HTML5 Apps Repo and accessible via a Launchpad module.

When calling the backend (the Node.js app) from the HTML5 application in the launchpad, the backend returns 401 unauthorized.
When accessing the backend (the Node.js app) directly via the App Router, the user is first redirected to the login screen and after successful login the backend can be accessed.

Do i have to make any further configuration to access the backend via the app router from the launchpad app.

App Router xs-app.json

{
    "authenticationMethod": "route",
    "welcomeFile": "/cp.portal",
    "routes": [
        {
            "source": "^/api/v4/(.*)$",
            "target": "$1",
            "destination": "api-service",
            "authenticationType": "xsuaa",
            "csrfProtection": false
        },
        {
            "source": "^(/.*)",
            "target": "$1",
            "service": "html5-apps-repo-rt",
            "authenticationType": "xsuaa"
        }
    ]
}

HTML5 Module xs-app.json

{
    "welcomeFile": "/index.html",
    "authenticationMethod": "route",
    "logout": {
        "logoutEndpoint": "/do/logout"
    },
    "routes": [
        {
            "source": "^/api/(.*)$",
            "target": "/api/$1",
            "destination": "DevAppRouter",
            "authenticationType": "xsuaa",
            "csrfProtection": false
        },
        {
            "source": "^(.*)$",
            "target": "$1",
            "service": "html5-apps-repo-rt",
            "authenticationType": "xsuaa"
        }
    ]
}

Die Destination DevAppRouter wurde im Dev Space in der Service Instance zum Destination Service erstellt.

server.js of the backend

...
var passport = require('passport');
var xsenv = require('@sap/xsenv');
var JWTStrategy = require('@sap/xssec').JWTStrategy;
...
var app = express();
var services = xsenv.getServices({ uaa: { tag: "xsuaa" } });
passport.use(new JWTStrategy(services.uaa));
app.use(passport.initialize());
app.use(passport.authenticate('JWT', { session: false }));

Configuration mta.yaml

- name: api-service
      type: nodejs
      path: modules/api-service/srv
      parameters:
          disk-quota: 512M
          memory: 256M
      provides:
          - name: api-service
            properties:
                url: ${default-url}
      requires:
          - name: application-logging
          - name: hdi-container
          - name: uaa
          - name: connectivity-tunnel
          - name: destination
- name: app-router
      type: approuter.nodejs
      path: scp/app-router
      parameters:
          disk-quota: 256M
          memory: 128M
          SAP_JWT_TRUST_ACL: [{ "clientId": "*", "identityzone": "*" }]
      requires:
          - name: api-service
            group: destinations
            properties:
                forwardAuthToken: true
                strictSSL: false
                name: api-service
                url: ~{url}
          - name: frontend-portal-resources
          - name: frontend-html5-repo-runtime
            properties:
                forwardAuthToken: true
          - name: application-logging
          - name: uaa
          - name: connectivity-tunnel
          - name: destination
      properties:
          SEND_XFRAMEOPTIONS: false

xs-security.json

{
    "xsappname": "DemoApp",
    "tenant-mode": "dedicated",
    "description": "Security profile of called application",
    "scopes": [
        {
            "name": "uaa.user",
            "description": "UAA"
        }
    ],
    "role-templates": [
        {
            "name": "Token_Exchange",
            "description": "UAA",
            "scope-references": ["uaa.user"]
        }
    ]
}
0 Kudos

Hi sperstorfer,

Could you please show me the mta.yaml of your HTML5 application?

Thanks.

Tri

former_member194549
Contributor

Hi trimle

following is a small sample from the mta.yaml

- name: migration-app
  type: html5
  path: apps/migration-app
  build-parameters:
    supported-platforms: []
    builder: custom
    commands:
      - npm run build
    build-result: dist
- name: frontend-ui-deployer
  type: com.sap.html5.application-content
  path: scp/frontend-ui-deployer
  parameters:
    disk-quota: 512M
    memory: 128M
  requires:
    - name: frontend-html5-repo-host
  build-parameters:
    requires:
      - name: migration-app
        artifacts:
          - "./*"
        target-path: resources/migration-app

Regards
Simon

0 Kudos

Hi sperstorfer,

Thanks for your code.

I've tried your way, set the destination with OAuth2UserTokenExchange pointing to the service api.

But I'm getting error Code: 500 Internal Server Error. Not sure if you got the error before.

Thanks.

Tri

Accepted Solutions (1)

Accepted Solutions (1)

joachimvanpraet
Active Participant
0 Kudos

Hi,

I think this has something to do with the fact you are using the "api-service" destination in the first app-router and "DevApprouter" in the HTML5 approuter.

The DevApprouter destination has NoAuthentication. If you want to setup SSO to this destination, please set the authentication type to OAuth2UserTokenExchange.

client id and client secret you can get from following command:

$ cf env <your_app_name>

in the credentials object of your xsuaa service.

Token Service Url: https://<cf_org>.authentication.eu10.hana.ondemand.com/oauth/token/alias/<cf_org>.aws-live-eu10

kr,

Joachim

former_member194549
Contributor

Hi Joachim,

you where right. Changing the destination to OAuth2UserTokenExchange did the job.
We already tried AppToAppSSO because we thought it would forward the token as well, but apparently it was wrong.

Following our final scenario:

  1. Launchpad (via portal service) containing the app uses the destination A (with OAuth2UserTokenExchange and points to the app router to get the app from the HTML5 repo)
  2. App router forwards the request to the HTML5 repo which contains the app files
  3. The HTML5 repo uses destination B (with OAuth2UserTokenExchange and points to the api service)
  4. App router forwards to api service, our node backend

I hope I could explain this well

Thank you Joachim for your answer.

Best regards

PS:
Following a link to the setup of the destination with OAuth2UserTokenExchange.

https://blogs.sap.com/2019/06/26/sap-cloud-platform-backend-service-tutorial-28-scenario-approuterno...

former_member194549
Contributor
0 Kudos

UPDATE:

Setting the authentication of the destination to "NoAuthentication" and the property forwardAuthToken of the destination to true does also the job.

This also works if the destination B points to the App Router, so that the App Router is the single point of entry.

Link: (i set the property forwardAuthToken, not HTML5.ForwardAuthToken)

https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/3cc788ebc00e40a091505c6b3fa...

Answers (0)