Skip to Content
Technical Articles

Appendix D: Using SAML with Kapsel

Previous   Home   Next

Here are a few terms that are used with SAML.
An identity provider (IdP) maintains a directory of users and provides authentication.
A service provider is the web site or service that is being accessed.
A user is the person who has an account with the identity provider.

When a user starts a Kapsel app that has been configured to use SAML, the SMP or SAP Cloud Platform Mobile Services server will send a request to the app to redirect to the identity provider if it does not have a valid token. Once the identity provider validates the user, a SAML token is returned that grants the application access for a certain length of time. If the SAML token is compromised it is only valid for a limited length of time against a specific application. Multiple applications can use the same identity provider so multiple applications can use the same user name and password, X.509 certificate or perhaps even a biometric like a fingerprint.

For additional details on SAML see the following links.
Enabling Secure Onboarding Using SAML
SAML 101 Video
Enabling Secure Onboarding Using SAML
Authenticate Applications Using SAML 2.0
Default Identity Federation with SAP ID Service
SAP Cloud Platform Identity Authentication Service Blueprint
Authenticate Applications Using SAML 2.0

The following sections demonstrate using SAML in a Kapsel app.
Registering using SAML with SAP Cloud Platform Mobile Services
Client Certificates and SAML
Handling Session Timeout
Offline Considerations
Known Issues

Registering using SAML with SAP Cloud Platform Mobile Services

The following steps demonstrate how to configure the Logon example to use SAML as the authentication provider for the application.

  • Using the SAP Cloud Platform Mobile Services cockpit, modify the Security Configuration of the application from Basic to Form.
    Form indicates SAML should be used. The identity provider for the SAP Cloud Platform Mobile Services trial server is

    and it requests your SAP Community credentials.

  • On the Backend tab, delete the SSO provider and add a new Basic Authentication provider but this time specify the user name and password required to access the OData service.
  • Modify the context variable in LogonDemo\www\serverContext.js to indicate that SAML should be used by adding.
    "auth": [ {
        "type": "",
        "config": {
            "": "",
            "": "/SAMLAuthLauncher",
            "": "finishEndpointParam"
    } ],
  • Add the settings plugin so that the user name of the authenticated user can be queried.
    cordova plugin add kapsel-plugin-settings --searchpath %KAPSEL_HOME%/plugins
    cordova plugin add kapsel-plugin-settings --searchpath $KAPSEL_HOME/plugins
  • Modify the index.html file and add the following button.
    <button onclick="sap.Settings.getConfigProperty(function(value) {alert(value)}, errorCallback, 'UserName')">Get User Name</button>
  • Prepare, build and deploy the app with the following command.
    cordova run android
    cordova run ios
    cordova run windows -- --archs=x64

    Note, if the Remember me checkbox is checked, a cookie will be set that will remain valid for three months so the user name and password will not need to be re-entered.

Client Certificates and SAML


If the SAML IdP presents the client with a certificate challenge the following screens will appear to allow the user to register with an installed certificate.

This screen will appear if the user has not configured a PIN or password on their device.

If you do not wish the user to see this screen, handling of client certificate challenges can be disabled by the following setting in the config.xml.

<preference name="SAPKapselHandleX509Challenges" value="false" />


Note that certificates installed on the system store (Settings > General > Profiles & Device Management) on iOS are not available to the app. For further information see Making Certificates and Keys Available To Your App. One technique to get a certificate into the apps keychain is to use a Mobile Device Management software such as SAP Afaria or Mobile Iron to provision the user certificate into the shared keychain.

Another technique where the certificate is loaded by one app and its keychain is shared with another app is demonstrated in the OAuth section.

If there are no certificates in the shared keychain the certificate dialog will not appear.

If there is only one certificate and the following method is called in the deviceready event, the certificate will be used automatically.

sap.AuthProxy.setAutoSelectCertificateConfig(successCB, errorCB, true);

If there are multiple certificates in the shared keychain the user will be prompted to select one.


On windows, if you do not wish the app to use a client certificate, remove the Shared User Certificates capability as shown below.

Handling Session Timeout

Note, the following information applies to SP14 and previous versions. In SP15, the Kapsel plugins were updated to automatically handle the expiration of a session.

A session is maintained between the client and the SMP or SAP Cloud Platform Mobile Services server. By default, it times out after 20 minutes of inactivity. See also Authentication and Handling Session Timeout.
When the application starts an attempt is made to refresh the session. This behavior can be disabled via the setting refreshSAMLSessionOnResume which is discussed further in the Offline Considerations.

If the WebView makes a request such as to open a page proxied through the SAP Cloud Platform Mobile Services server and the session has timed out, the WebView is redirected to the IdP to refresh the session. The original requested page is then shown after the redirect.
To simulate this add the following code to index.html.

function logout() {
    updateStatus2("Calling logout");
    var sUrl = "https://" + applicationContext.registrationContext.serverHost + ":" + applicationContext.registrationContext.serverPort + "/mobileservices/sessions/logout";
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4) {
            updateStatus2("Successfully Logged Out");
            console.log("SUCCESS " + xmlhttp.responseText + " " + xmlhttp.status)
    }"POST", sUrl, true);
    xmlhttp.setRequestHeader("Content-Type", "application/json");

function openProxiedURL() {
    var sUrl = "https://" + applicationContext.registrationContext.serverHost + ":" + applicationContext.registrationContext.serverPort + "/" + appId;, "_self"); 

Then near the bottom of the index.html file add the following two buttons.

<button onclick="logout()">Logout</button>
<button onclick="openProxiedURL()">Open Proxied URL</button>

Modify the config.xml and add the following line which enables the WebView to be navigated to a new URL.

<allow-navigation href="*" />

Deploy and run the modified app. Notice that it is now possible to end the session between the app and the SAP Cloud Platform Mobile Services server by pressing the Logout button. If a request is then made to open a proxied URL, the SAP Cloud Platform Mobile Services server directs the app to the IdP to first get a SAML session. Note, the session between the app and the SAP Cloud Platform Mobile Services server can also be terminated by removing the app from memory.

If the request is made with an XMLHttpRequest or with datajs, extra code is required to detect that the session has expired and needs to be refreshed.
Try pressing Logout and then Read. Notice that an HTML page was returned rather than an ODATA result.

Add the below code to the top of the errorCallback method to handle this case.

function errorCallback(e) {
    if (e.hasOwnProperty("response")) {
        if (e.response.hasOwnProperty("headers")) {
            if (e.response.headers.hasOwnProperty("")) {
                alert("SAML session has expired.  Please retry the operation after the session has been re-established.");
                sap.Logon.performSAMLAuth(function () {}, errorCallback);

Note, a handler could also be added with the below code. The method mySAMLHandler would be called whenever the app receives a response that includes the header.

function mySAMLHandler(calledURL) {
    //TODO display error, call performSAMLAuth

sap.AuthProxy.setSAMLChallengeHandler(function() {}, function() {}, mySAMLHandler, context.auth[0].config);

Offline Considerations

Note, the following information applies to SP14 and previous versions. In SP15, the Kapsel plugins were updated to automatically handle the expiration of a session.

When the application starts an attempt is made to refresh the SAML token. For an offline app that opens when there is no network connectivity this request will fail.

LogonJSView: error sending initial SAML request{"errorCode":-1,"description":"Unknown Error. Details : Unable to resolve host \"\": No address associated with hostname."}

To disable this refresh attempt on startup, add the following value to the serverContext.js file.

"refreshSAMLSessionOnResume": "skip",  //skip, always(default)

This indicates that after the initial registration, it is up to the application to renew the SAML session. Before this setting takes effect, you may need to unregister and re-register if a previous registration exists.

Known Issues

If you are using a custom identity provider, it is recommended to use a POST binding rather than a REDIRECT binding.

Previous   Home   Next

You must be Logged on to comment or reply to a post.
    • Thanks for the feedback.  I added a link back to the first part of the blog series at the top in addition to the existing one at the bottom.


      Dan van Leeuwen

  • Hi,

    Thanks for this blog post .. very helpful hints.

    I was wondering if there is any good tutorial on using oauth with kapsel applications. Is there any blog describing how to implement this?

    Best Regards,

    Edmund Hupf

    • I believe you could change the IDP used by the SAP Cloud Platform Mobile Services server (HCP) but I think the SAP Cloud Platform Mobile Services server is required.

      Dan van Leeuwen

  • Hello Daniel,

    Thanks for your Kapsel blog, very helpful.

    I have a related issue on HCPms (Mobile Service for Development and Operations into SAP Cloud Platform).

    Is it possible to remove HCPms sessions from the Kapsel App, just in a similar way you do in the function logout() of your sample?

    Trying "logoutPage": "<path to logout page>" into neo-app.json does not seem to work.

    I'm using SAP Business ByDesign as backend of my Kapsel App. Also provide a Form in order to login into ByD with a specific ByD User. This is working fine, the problem is in the logout. I didn't fine the way to remove the ByD session created by the form, so even I try to login again, the old session still continue.

    Here is the problem description post (just in case):

    Thanks in advance and regards,

    Óscar Espinar Lázaro


  • Hi Daniel,

    Thanks a lot for this blog!
    I followed step-by-step and now I have SAML authentication using ADFS, which is great. I have one last thing that I couldn't find regarding SSO propagation. Basically, I have a SAP Cloud Connector with some Gateway endpoints and I tried to set up as "Destinations" at SCP and also Mobile Service for Development and Operations. I tried to configure two types of Destinations: Cloud Platform Destination (it worked with basic and harcoded credentials) and Mobile Destination (not possible because when I added the url it says “Invalid URL. Only ‘http://’ is allowed for OnPremise Destination”). I wondering what's the proper configuration to set up the Destinations in order to propagate the SAML auth as a SSO to the backend endpoint.

    Thanks again


    • Proxy type setting of OnPremise indicates that the URL is a virtual URL that points to a Cloud Connector.  So, if the URL you are pointing at is not available on the internet, then you could use the SAP Cloud Connector to connect from you SAP Cloud Platform Mobile Services to your on premise system.  See also

      Dan van Leeuwen


    Hi Daniel,

    Last question: do you have any tip or post regarding how to call a mobile services' API/Destination using SAML auth from the app?
    I tried using Postman to get Application Connection ID or fetch X-CSRF-Token in the registration API but it always responses the IDP (ADFS in my case). I found AppID and the token debuging the app but I cannot call the API/Destinations sending X-CSRF-Token as header in the app or with Postman. I get a 401 error. The OData Application Destination Test works perfect with the same user that I'm triying within the app. Thanks!

  • Hi Daniel,


    Maybe i'm looking over it, but when using SAML for the login, using your "register()" function, will  trigger the SCP login page, but afterwards, I stay on the "Loading..." screen because I don't see in which success function it returns the context.

    Do we need to use another login method for SAML insead of following one?

    function register() {
    logonInitTime =;
    updateStatus2("Calling Logon.init");
    sap.Logon.init(logonSuccessCallback, logonErrorCallback, appId, context);


    • I recreated the project and was not able to reproduce the problem.  I used an Android emulator.  Perhaps double check that you have changed the authentication tab to use SAML in your application and have added the auth parameter in your serverContext.js file.

      If it would help, message me directly and I can share the project.


      Dan van Leeuwen



      • it appeared that there was an issue in saml2.js (in the errorListener).

        Because we’re using windows, following code was missing in the error Listener.
        because I had an issue, I never saw what it was, but now this is also fixed.

        if (cordova.require(“cordova/platform”).id.indexOf(“windows”) === 0) {

        But If you would like to follow me also, so I can send you some additional questions, that would be very helpfull 🙂