Skip to Content
Technical Articles

Adding authentication to Approuter with XSUAA binding in Kyma runtime

Pre-read:

This blog requires basic knowledge of kyma runtime, if you are not aware of it you can refer to the following sources:

 SAP Help Documentation on Kyma

Kyma Project

XSUAA

Contents

This blog contains the following information:

  • How to create XSUAA instance in kyma runtime.
  • How to bind create secrets for XSUAA instance.
  • How to bind secret to Approuter using volume mounts.
  • Exposing the router to the public internet

 

Let’s get started:

The first step is to create an xsuaa service instance, we will be doing it through yaml.

  
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: garouter-uaa
  namespace: <your-namespace>
spec:
  clusterServiceClassExternalName: xsuaa
  clusterServicePlanExternalName: application
  parameters:
    xsappname: garouter
    tenant-mode: dedicated
    oauth2-configuration:
      redirect-uris:
        - "https://garouter.<your kyma host>.com/login/callback"
    scopes:
      - name: "$XSAPPNAME.admin"
        description: Admin
    role-templates:
      - name: admin
        description: Admin
        scope-references:
          - "$XSAPPNAME.admin"

It can also be created by passing the above configuration using JSON format, for details you can refer to this blog

Well now that we have the xsuaa configuration, let’s also add the configuration for service binding:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: routerauth-binding
  namespace: <your-namespace>
spec:
  instanceRef:
    name: garouter-uaa
  secretName: routerauth-binding

My app-router is very basic at this moment where it’s having xs-app.json where I have defined routes and one plain HTML page.

xs-app.json

{
    "welcomeFile": "index.html",
    "authenticationMethod": "route",
    "routes": [
        {
            "source": "^/(.*)",
            "authenticationType": "xsuaa",
            "localDir": "resources"
        }
    ]
}

Now to deploy the router We need to containerize the app. I’m using docker for this purpose. Here’s the docker file:

FROM node:10-slim

# Execute docker build from top-level project directory

WORKDIR /usr/src/app
COPY . .
RUN npm install

EXPOSE 5000
CMD [ "npm", "start" ]

Once you have built the image and pushed it to the docker hub. Let’s create a deployment file.

One thing to note is that SAP’s approuter Use’s @sap/xsenv package internally to parse and load service keys and secrets bound to the application, this makes the process to load secrets easy.

@sap/xsenv loads the secret in the following manner

/etc/
    /secrets/
            /sapcp/
                 /hana/
                 |    /hanaInst1/
                 |    |          /user1
                 |    |          /pass1
                 |    /hanaInst2/
                 |               /user2
                 |               /pass2
                 /xsuaa/
                       /xsuaaInst/
                                  /user
                                  /pass

You can read more about it at  @sap/xsenv

Now let’s look at deployment configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: gopal
  name: garouter
  labels:
    app: garouter
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: garouter
      version: v1
  template:
    metadata:
      namespace: gopal
      labels:
        app: garouter
        version: v1
    spec:
      containers:
        - name: garouter
          image: <docker registry/image>
          imagePullPolicy: Always
          resources:
            limits:
              memory: 512Mi
              cpu: "1"
            requests:
              memory: 256Mi
              cpu: "0.2"
          ports:
            - containerPort: 5000
          volumeMounts:
            - name: garouter-uaa
              mountPath: "/etc/secrets/sapcp/xsuaa/garouter-uaa" # here garouter-uaa is instance name of xsuaa
              readOnly: true
      volumes:
        - name: garouter-uaa
          secret:
            secretName: routerauth-binding # secret name created at service binding level

Now let’s create a service and API to make it accessible to the internet:

---
apiVersion: v1
kind: Service
metadata:
  namespace: gopal
  name: garouter
  labels:
    app: garouter
    service: garouter
spec:
  ports:
    - port: 5000
      name: http
  selector:
    app: garouter

---
apiVersion: gateway.kyma-project.io/v1alpha1
kind: APIRule
metadata:
  name: garouter
  namespace: gopal
spec:
  gateway: kyma-gateway.kyma-system.svc.cluster.local
  rules:
    - accessStrategies:
        - config: {}
          handler: allow
      methods:
        - GET
        - POST
        - PUT
        - PATCH
        - DELETE
        - HEAD
      path: /.*
  service:
    host: garouter.<your domain>.ondemand.com
    name: garouter
    port: 5000

Well, now let’s put all these configurations together, and use the command

kubectl apply -f deployment.yaml

Once everything is created, let’s go to the API rules section on kyma consume and launch our application.

Login page(looks like this because I have multiple Identity providers):

 

The application:

🎆 fireworks. It’s working.

If you want to see the router code or deployment.yaml you can find here.

Further reading:

Deploy CAP Application on kyma

SAP S/4HANA Extended Business Process Scenario

ECC Extend Business Process Scenario

Be the first to leave a comment
You must be Logged on to comment or reply to a post.