Authentication

Authentication


SAML 2.0 in the SAP BTP SDK for iOS

 Implementing SAML authentication

There are several combination of configurations how the SAML authentication can be implemented using the SDK. This section lists the most common and important scenarios.

1. General usage against SAPcpms

This scenario is the most common and the SDK-suggested way of implementing the process.

SAML challenges happen as a result of a network request, therefore it is convenient to authenticate at this point. The SAMLObserver component is capable of detecting SAML challenges in the network requests’ response and starting the SAML authentication flow.

Example:

// Create the observer using the SAPcpms settings parameters
let samlObserver = SAMLObserver(settingsParameters: <#your SAPcpmsSettingsParameters#>)

// Register the created observer to an instance of the SAPURLSession
sapURLSession.register(samlObserver)

SAPcpmsSettingsParameters is required to use this convenience method. When the authentication is against SAPcpms it is expected to have (or to be able to create) an instance of this object. See more about at SAPcpmsSettingsParameters.

SAPURLSession is required to register the created SAMLObserver. This url session has to be the one which will communicate with the SAML protected resources.

IMPORTANT: An observer instance can be registered only once to the same SAPURLSession! Registering the same instance of observer multiple times will result in application termination!

2. Customization - custom authenticator URLs

Hence the convenince initializations there could be scenarios where to default mechanism is not applicable. This usually happens when the authentication is not against SAPcpms. The SDK supports the customization of the authenticator and the observer.

The SAMLAuthenticator needs two URLs to perform the SAML authentication in the web view. These are namely the authorizationEndpointURL and finishEndpointURL. When using the convenience initializer with the SAPcpmsSettingsParameters these URLs are constructed as follows:

Where the https://www.myhost.com is the backendURL from SAPcpmsSettingsParameters.

If this URL construction is not applicable to your landscape then you can provide these URLs yourself in an instance of SAPcpmsSettingsParameters.

Example:

// Define your landscape's URLs
let authorizationEndpointURL = <#My authentication endpoint URL#>
let finishEndpointURL = <#My finish endpoint URL#>

// Create the authentication parameters with your custom URLs
let authenticationParameters = SAMLAuthenticationParameters(authorizationEndpointURL: authorizationEndpointURL, finishEndpointURL: finishEndpointURL)

// Use the initializer which takes SAML authentication parameters
let samlObserver = SAMLObserver(authenticationParameters: authenticationParameters)

// Register the created observer to an instance of the SAPURLSession
sapURLSession.register(samlObserver)

See more at SAMLAuthenticationParameters.

3. Customization - custom SAML challenge detection

SAPcpms signals SAML challenges through HTTP response headers. The default SAML challenge implemented by SAPcpms:

  • HTTP response status code 200
  • Custom header name “com.sap.cloud.security.login” with value “login-request”

The default SAMLObserver looks for these conditions on every received response to determine if there was a SAML challenge. If your landscape signals SAML challenges differently then you need to customize the challenge detection logic. The SDK supports this kind of customization through the sub-classing of SAMLObserver and the overriding of the dedicated challenge detection method.

Example:

class MySAMLObserver: SAMLObserver {
    // Override the default challenge detection method
    override func isChallenge(dataTask: SAPURLSessionTask, response: URLResponse) -> Bool {
        // Determine if the response contains a SAML challenge
        // Return a boolean value accordingly.
        // return true - the repsonse is a SAML challenge and authentication must take place
        // return false - the response is not a SAML challenge, continue normally
    }
}

// Create your observer with one of the available initializers
let mySAMLObserver = MySAMLObserver(settingsParameter: <#your SAPcpmsSettingsParameters#>)

// Register the created observer to an instance of the SAPURLSession
sapURLSession.register(mySAMLObserver)

Inside the func isChallenge(dataTask:response:) method everything is available regarding the ongoing http request. If you determine that the received response is indeed a SAML challenge then you must return true, which will start the authentication flow. Return false if the response is not SAML challenge.

4. Customization - custom web view presenter

SAML authentication requires a web view to present the login page in. For this functionality the web view presenter is implemented. A presenter puts up a new view controller contaning a web view on top of the view hierarchy. By default the SAMLAuthenticator uses the WKWebViewPresenter class to achieve this goal. If the default presentation style or looks are not sufficient then you can implement your version of the web view presenter and use it for authentication.

SAML authentication currently supports only WKWebView thus the implementation of WKWebViewPresenting protocol is required for custom presentation. See more at SAMLAuthenticator - using your own web view presenter implementation

5. Preauthentication

The general case is to authenticate when a request encountered with a SAML challenge. However this request could be sent too far in the application’s lifecycle and having a web view pop up at that point could be unpleasing.

The SDK supports a way to implement preauthentication at application startup. This requires to instantiate the SAMLAuthenticator separately. A direct call to the SAMLAuthenticator‘s func authenticate(completionHandler:) will start the authentication flow. See more about at SAMLAuthenticator.

Example:

// Create the authenticator using the SAPcpms settings parameters
let authenticator = SAMLAuthenticator(settingsParameters: <#your SAPcpmsSettingsParameters#>)

// Start the authentication flow directly
authenticator.authenticate { error in
    if let error = error {
        // If there was an error during the authentication process then the `error` contains the cause of it.
        // Requests to SAML proctected resources will result in SAML challenge.
        // The authentication has to be repeated.
    }
    // If there was no error (the `error` is `nil`) then the authentication was successful.
    // Requests to SAML protected resources should not encounter SAML challenges.
}

SAPcpmsSettingsParameters is required to use this convenience method. When the authentication is against SAPcpms it is expected to have (or to be able to create) an instance of this object. See more about at SAPcpmsSettingsParameters.

Note: According to SAML standard, challenges could happen any time during the application lifecycle. Therefore the forward authentication mechanism is not sufficient in all cases hence its convenience. It is recommended to add a SAMLObserver to the SAPURLSession instance, after the direct authentication. See more at the previous chapter or at SAMLObserver.

End to end SAML 2.0 flow

The overall SAML 2.0 authentication flow across client and server is described here: SAML 2.0 at SAP. This section explains the different steps and how the SDK supports the developer in each step. See Client Authentication with SAML for additional information.

  1. In general SAML authentication happens when a network request encounters a SAML challenge. SAML challenges are detected using a specific header in the response, which is a simple key-value pair. This behaviour can be customized if required.

    See SAMLObserver for further information.

  2. After a SAML challenge is detected, the authentication must take place. The authentication happens in a web view. Therefore, a SAML-protected URL has to be provided, which will be loaded in the web view to trigger the actual SAML flow and load the login page in that web view. In the default setup, this URL can point to an existing, pre-configured, blank resource on SAP Mobile Services, which is SAML protected: https://<SAPcpmsHost>/SAMLAuthLauncher. See authorizationEndpointURL for details.
    When accessing the SAML-protected resource, the response redirects the web view to the IdP that is configured for your SAP BTP account for authentication. This behavior is achieved by a JavaScript redirect.

  3. Following the successful authentication, the SAML authenticator must be notified so it can resend the original request. Since the authentication flow happens in a system web view, the only option to notify the authenticator about state changes is to redirect the web view to a specific URL which can be observed from outside the web view. The original authorizationEndpointURL must return a redirect to that specific URL after authentication, i.e. if the client has a valid session and no SAML flow needs to be performed. See finishEndpointURL for details.
    The /SAMLAuthLauncher resource includes that behavior and automatically redirects the client to /SAMLAuthLauncher?finishEndpointParam=someUnusedValue, if the client has a valid session.

    Note: The authentication flow uses a web view redirect, because the original request was a native request and the authentication takes place in a web view context. The native - web context switch is resolved by SAP using this method, and is not SAML specific.

  4. After successful authentication, the original request (which triggered the authentication initially) is resent.

SAP BTP limitation for SAML and FORM authentication: if your application sends multiple simultaneous requests without an authenticated session, they may fail. SAP recommends that you first send one request to a protected resource, establish a session, and then use the session for the multiple simultaneous requests.

OAuth 2.0 in the SAP BTP SDK for iOS

 Implementing OAuth authentication

There are several combination of configurations how the OAuth 2.0 authentication can be implemented using the SDK. This section lists the most common and important scenarios.

1. General usage

The most common and sdk-suggested way to implement the authentication is the use of the convenience initializers. Only the OAuth2AuthenticationParameters and an instance of SAPURLSession is required beforehand.

// Create the wrapper with the server side configuration
let authorizationEndpointURL = URL(string: "<#URL String#>")!
let tokenEndpointURL = URL(string: "<#URL String#>")!
let tokenRedirectURL = URL(string: "<#URL String#>")!
let clientID = "<#Client ID hash#>"
let scopes = Set<String>()
let parameters = OAuth2AuthenticationParameters(authorizationEndpointURL: authorizationEndpointURL, clientID: clientID, redirectURL: tokenRedirectURL, tokenEndpointURL: tokenEndpointURL, requestingScopes: scopes)

// Create the OAuth2Observer using the convenience initializer
let observer = OAuth2Observer(authenticationParameters: parameters, tokenStore: self)

// Register the newly created observer
sapURLSession.register(observer)

The example above assumes that the class in which it is executed implements the OAuth2TokenStore protocol, therefore it can pass self as the tokenStore. It is also assumed to have a sapURLSession which is an instance of SAPURLSession.

By following this method, the OAuth2Authenticator is implicitly instantiated with a new instance of SAPURLSession.

Note: The OAuth2Authenticator uses SFSafariViewController by default. See more at Using the default web view presenter section of the OAuth2Authenticator.

2. Customization - custom SAPURLSession

There could be scenarios when the implicitly created SAPURLSession instance is not sufficient, using the convenience initializer. This is usually the case when the authorization endpoint has a custom requirement for HTTP requests or requires authentication itself. A custom created (and configured) SAPURLSession instance can be created and set to use with the component. This way of implementing the authentication requires the seperate instantiation of OAuth2Authenticator and OAuth2Observer.

Example:

// Create and configure the custom SAPURLSession
let customSAPURLSession = SAPURLSession()
// ... SAPURLSession configuration ...

// Create the wrapper with the server side configuration
let authorizationEndpointURL = URL(string: "<#URL String#>")!
let tokenEndpointURL = URL(string: "<#URL String#>")!
let tokenRedirectURL = URL(string: "<#URL String#>")!
let clientID = "<#Client ID hash#>"
let scopes = Set<String>()
let authenticationParameters = OAuth2AuthenticationParameters(authorizationEndpointURL: authorizationEndpointURL, clientID: clientID, redirectURL: tokenRedirectURL, tokenEndpointURL: tokenEndpointURL, requestingScopes: scopes)

// Create the OAuth2Authenticator with the custom SAPURLSession
let authenticator = OAuth2Authenticator(authenticationParameters: authenticationParameters, sapURLSession: customSAPURLSession)

// Create the observer using the authenticator
let observer = OAuth2Observer(authenticator: authenticator, tokenStore: self)

// Register the created observer
sapURLSession.register(observer)

The example above assumes that the class in which it is executed implements the OAuth2TokenStore protocol, therefore it can pass self as the tokenStore. It is also assumed to have a sapURLSession which is an instance of SAPURLSession.

3. Customization - XSUAA Authorization URL

A new optional parameter called oauth2.xsuaaAuthorizationURL is introduced in the ConfigurationProvider.plist to improve the overall onboarding performance. This parameter is not mandatory, it’s only optional and if it’s added, it will improve the time taken for the onboarding. If this parameter is provided, the oauth2.xsuaaAuthorizationURL URL will be called instead of the oauth2.authorizationEndpointURL.

There are two ways that this parameter can be retrieved and added in the ConfigurationProvider.plist.

Automatic

If you use the assistant generated application, this parameter gets automatically added in the ConfigurationProvider.plist as oauth2.xsuaaAuthorizationURL after the application creation.

Manual

If your existing application doesn’t have oauth2.xsuaaAuthorizationURL in the ConfigurationProvider.plist, you have to create an entry called oauth2.xsuaaAuthorizationURL under config in the ConfigurationProvider.plist and retrieve the value by downloading the onboarding configuration from the APIs tab of the application details page in the CPms cockpit : https://help.sap.com/doc/f53c64b93e5140918d676b927a3cd65b/Cloud/en-US/docs-en/guides/getting-started/admin/manage.html

Note: This parameter will work only for OAuth authentication and WKWebViewPresenter webview. Also, this will work only on CF platform and not on NEO platform.

4. Customization - custom OAuth 2 challenge detection

SAPcpms signals OAuth 2 challenges through HTTP status codes and response headers. The default OAuth 2 challenge implemented by SAPcpms:

  • HTTP response status code 401
  • Custom header name “X-SMP-AUTHENTICATION-STATUS” with value “1000”

The default OAuth2Observer looks for these conditions on every received response to determine if there was an OAuth 2 challenge. If your landscape signals OAuth 2 challenges differently then you need to customize the challenge detection logic. The SDK supports this kind of customization through the sub-classing of OAuth2Observer and the overriding of the dedicated challenge detection method.

Example:

class MyOAuth2Observer: OAuth2Observer {
    // Override the default challenge detection method
    override func isChallenge(dataTask: SAPURLSessionTask, response: URLResponse) -> Bool {
        // Determine if the response contains an OAuth 2 challenge
        // Return a boolean value accordingly.
        // return true - the repsonse is an OAuth 2 challenge and authentication must take place
        // return false - the response is not an OAuth 2 challenge, continue normally
    }
}

// Create your observer with one of the available initializers
let myOAuth2Observer = MyOAuth2Observer(authenticationParameters: parameters, tokenStore: self)

// Register the created observer to an instance of the SAPURLSession
sapURLSession.register(myOAuth2Observer)

Inside the func isChallenge(dataTask:response:) method everything is available regarding the ongoing http request. If you determine that the received response is indeed an OAuth 2 challenge then you must return true, which will start the authentication flow. Return false if the response is not OAuth 2 challenge.

5. Customization - custom web view presenter (Authorization Code Grant only)

OAuth 2 Authorization Code authentication requires a web view to present the login page in. For this functionality the web view presenter is implemented. A presenter puts up a new view controller contaning a web view on top of the view hierarchy. By default the OAuth2Authenticator uses the SFSafariViewControllerPresenter class to achieve this goal. If the default presentation style or looks are not sufficient then you can implement your version of the web view presenter and use it for authentication.

End to end OAuth 2.0 flow

The standard OAuth 2.0 flow implementation is described here: OAuth 2.0 at SAP. Currently the “Authorization Code Grant” and “Client Credentials Grant” flows are supported in the SDK. This section explains the different steps and how the SDK supports the developer in each step. See Client Authentication with OAuth2 for additional information.

  1. By default, OAuth 2 challenges are detected by observing the HTTP response status code (and a custom header in case of SAP BTP). See OAuth2Observer for further information.
  2. After the OAuth 2 challenge is detected, the authentication (or refresh) must take place.

Notes:

Authorization Code Flow

Authentication
  1. The authentication happens in a web view login page, therefore the URL of the OAuth 2 authorization server must be provided, which is loaded in the web view. See authorizationEndpointURL for details.
  2. The URL expected by the server contains multiple parameters which is assigned during runtime. The included parameters are (See OAuth2AuthenticationParameters for details):
    • clientID
    • redirectURL
    • requestingScopes
    • state
  3. Following the successful authentication at the IdP and the authorization option at the authorization page, the server makes a redirect to the specified redirectURL, adding a code parameter to the URL, containing the authorization code.
    Using the default web view presenter, the application must catch the redirection event as described here: Using the default web view presenter.
  4. The client issues a native POST request to the tokenEndpointURL, containing the authorization code.
  5. The expected response of this request is a JSON payload containing access_token, refresh_token, token_type, expires_in and scope, which are internally used to create the OAuth2Token.6. After successful authentication, the original request resent.
  6. After successful authentication, the original request is resent using the appropriate authorization header.
Refresh

When an authentication challenge is detected, but the client already has a token, it can use its refreshToken property to renew the token:

  1. The client issues a native POST request to the tokenEndpointURL, containing the refresh token property.
  2. The response of this request is a serialized token which is internally used to create the OAuth2Token.
  3. After a successful refresh, the original request resent.

Client Credentials

Authentication
  1. The authentication happens in a background process.
  2. The URL expected by the server contains multiple parameters which is assigned during runtime. The included parameters are (See OAuth2ClientCredentialsAuthenticationParameters for details):
    • requestingScopes
  3. The client issues a native POST request to the tokenEndpointURL, containing the authentication parameters.
  4. The expected response of this request is a JSON payload containing access_token, token_type, expires_in and scope, which are internally used to create the OAuth2Token.
  5. After successful authentication, the original request is resent using the appropriate authorization header.

OTP in the SAP BTP SDK for iOS

 Implementing OTP authentication

There are several combination of configurations how the OTP authentication can be implemented using the SDK. This section lists the most common and important scenarios.

1. General usage against SAPcpms

This scenario is the most common and the SDK-suggested way of implementing the process.

OTP challenges happen as a result of a network request, therefore it is convenient to authenticate at this point. The OTPObserver component is capable of detecting OTP challenges in the network requests’ response and starting the OTP authentication flow.

Example:

// Create the observer using the SAPcpms settings parameters
let otpObserver = OTPObserver(settingsParameters: <#your SAPcpmsSettingsParameters#>)

// Register the created observer to an instance of the SAPURLSession
sapURLSession.register(otpObserver)

SAPcpmsSettingsParameters is required to use this convenience method. When the authentication is against SAPcpms it is expected to have (or to be able to create) an instance of this object. See more about at SAPcpmsSettingsParameters.

SAPURLSession is required to register the created OTPObserver. This url session has to be the one which will communicate with the OTP protected resources.

IMPORTANT: An observer instance can be registered only once to the same SAPURLSession! Registering the same instance of observer multiple times will result in application termination!

2. Customization - custom authenticator URLs

Hence the convenince initializations there could be scenarios where to default mechanism is not applicable. This usually happens when the authentication is not against SAPcpms. The SDK supports the customization of the authenticator and the observer.

The OTPAuthenticator needs two URLs to perform the OTP authentication in the web view. These are namely the authorizationEndpointURL and finishEndpointURL. When using the convenience initializer with the SAPcpmsSettingsParameters these URLs are constructed as follows:

Where the https://www.myhost.com is the backendURL from SAPcpmsSettingsParameters.

If this URL construction is not applicable to your landscape then you can provide these URLs yourself in an instance of SAPcpmsSettingsParameters.

Example:

// Define your landscape's URLs
let authorizationEndpointURL = <#My authentication endpoint URL#>
let finishEndpointURL = <#My finish endpoint URL#>

// Create the authentication parameters with your custom URLs
let authenticationParameters = OTPParameters(authorizationEndpointURL: authorizationEndpointURL, finishEndpointURL: finishEndpointURL)

// Use the initializer which takes OTP authentication parameters
let otpObserver = OTPObserver(otpParameters: authenticationParameters)

// Register the created observer to an instance of the SAPURLSession
sapURLSession.register(otpObserver)

See more at OTPParameters.

3. Customization - custom OTP challenge detection

SAPcpms signals OTP challenges through HTTP response headers. The default OTP challenge implemented by SAPcpms:

  • HTTP response status code 200
  • Custom header name “x-smp-authentication” with value “otp-challenge”

The default OTPObserver looks for these conditions on every received response to determine if there was an OTP challenge. If your landscape signals OTP challenges differently then you need to customize the challenge detection logic. The SDK supports this kind of customization through the sub-classing of OTPObserver and the overriding of the dedicated challenge detection method.

Example:

class MyOTPObserver: OTPObserver {
    // Override the default challenge detection method
    override func isChallenge(dataTask: SAPURLSessionTask, response: URLResponse) -> Bool {
        // Determine if the response contains an OTP challenge
        // Return a boolean value accordingly.
        // return true - the repsonse is an OTP challenge and authentication must take place
        // return false - the response is not an OTP challenge, continue normally
    }
}

// Create your observer with one of the available initializers
let myOTPObserver = MyOTPObserver(settingsParameter: <#your SAPcpmsSettingsParameters#>)

// Register the created observer to an instance of the SAPURLSession
sapURLSession.register(myOTPObserver)

Inside the func isChallenge(dataTask:response:) method everything is available regarding the ongoing http request. If you determine that the received response is indeed an OTP challenge then you must return true, which will start the authentication flow. Return false if the response is not OTP challenge.

4. Automatic OTP flow

The SAPcpms supports automatic OTP flow via the SAP Authenticator application. You can find more info in the OTPAuthenticator’s documentation.

5. Customization - custom web view presenter

OTP authentication requires a web view to present the login page in. For this functionality the web view presenter is implemented. A presenter puts up a new view controller contaning a web view on top of the view hierarchy. By default the OTPAuthenticator uses the WKWebViewPresenter class to achieve this goal. If the default presentation style or looks are not sufficient then you can implement your version of the web view presenter and use it for authentication.

OTP authentication currently supports only WKWebView thus the implementation of WKWebViewPresenting protocol is required for custom presentation. See more at OTPAuthenticator - using your own web view presenter implementation

End to end OTP flow

The overall OTP authentication flow is described here: OTP at SAP. This section explains the different steps and how the SDK supports the developer in each step.

  1. In general OTP authentication happens when a network request encounters an OTP challenge. OTP challenges are detected using a specific header in the response, which is a simple key-value pair. This behaviour can be customized if required.

    See OTPObserver for further information.

  2. After an OTP challenge is detected, the authentication must take place. The authentication happens in a web view. In the default setup, the URL loaded in the web view is the following: https://www.myhost.com/mobileservices/OTPForm?redirecttooriginalurl=false The URL should present the OTP login form.

  3. Following the successful authentication, the OTP authenticator must be notified so it can resend the original request. Since the authentication flow happens in a system web view, the only option to notify the authenticator about state changes is to redirect the web view to a specific URL which can be observed from outside the web view. The original authorizationEndpointURL must return a redirect to that specific URL after authentication, i.e. if the client has a valid session and no OTP flow needs to be performed. See finishEndpointURL for details.

    Note: The authentication flow uses a web view redirect, because the original request was a native request and the authentication takes place in a web view context. The native - web context switch is resolved by SAP using this method, and is not OTP specific.

  4. After successful authentication, the original request (which triggered the authentication initially) is resent.

Logout

The SDK does not include an API to log out users, instead the application developer must create and send a simple HTTP request to the SAPcpms backend. The logout API URL on SAPcpms is: http[s]:// SAPcpms base URL /mobileservices/sessions/logout

Important: You must send the logout request with the same SAPURLSession instance you used for authentication. The logout API on SAPcpms expects session cookies, without them the logout is ineffective.

Example:

let logoutURL = URL(string: "https://<#SAPcpms base URL#>/mobileservices/sessions/logout")!
var logoutRequest = URLRequest(url: logoutURL)
logoutRequest.httpMethod = SAPURLSession.HTTPMethod.post

let sapURLSession = SAPURLSession() // Must be a SAPURLSession with the same cookie store that is used for authentication!
let logoutTask = sapURLSession.dataTask(with: logoutRequest) { data, response, error in
    // Process response
}
logoutTask.taskDescription = "SAPcpms logout request"
logoutTask.resume()

See Logout Service for additional information.

Authentication component Logger ID

This component uses the following name prefix for logging: ‘SAP.Foundation.Authentication’

  • Observer to collect the necessary credential for basic authentication

    See more

    Declaration

    Swift

    open class BasicAuthenticationObserver
    extension BasicAuthenticationObserver: SAPURLSessionObserving
  • The use of this component is the SDK-suggested way of implementing OAuth 2.0 authentication in the application. The OAuth2Observer allows a transparent OAuth authentication for HTTP requests. It sets the OAuth HTTP header on requests before they are sent. Moreover, it can detect failures that occur during OAuth authentication and handle authentication failures. It uses an OAuth2Authentication instance to authenticate and to refresh tokens. For token storing the OAuth2TokenStore is used.

    This component supports:

    Example use:

    // Create the wrapper with the server side configuration
    let authorizationEndpointURL = URL(string: "<#URL String#>")!
    let tokenEndpointURL = URL(string: "<#URL String#>")!
    let tokenRedirectURL = URL(string: "<#URL String#>")!
    let clientID = "<#Client ID hash#>"
    let parameters = OAuth2AuthenticationParameters(authorizationEndpointURL: authorizationEndpointURL, clientID: clientID, redirectURL: tokenRedirectURL, tokenEndpointURL: tokenEndpointURL)
    
    // Create the OAuth2Observer using the convenience initializer
    let observer = OAuth2Observer(authenticationParameters: parameters, tokenStore: self)
    
    // Register the newly created observer
    sapURLSession.register(observer)
    

    The example above assumes that the class in which it is executed implements the OAuth2TokenStore protocol, therefore it can pass self as the tokenStore. It is also assumed to have a sapURLSession which is an instance of SAPURLSession.

    See more

    Declaration

    Swift

    open class OAuth2Observer
    extension OAuth2Observer: SAPURLSessionObserving
  • The use of this component is the SDK-suggested way of implementing OTP authentication in the application. The OTPObserver intercepts requests provided by SAPURLSession and looks for OTP challenge indicating HTTP responses. Upon detecting an OTP challenge, it uses its OTPAuthenticator to authenticate and resend the original request when the authentication is successful. The caller does not notice anything from the authentication flow.

    Example use:

    // create or acquire the SAPURLSession instance
    let sapURLSession = SAPURLSession()
    
    // perform other steps to initialize the session and the application
    
    // create the SAPcpms settings parameter
    let settingsParameters = SAPcpmsSettingsParameters(backendURL: <#your backendURL#>, applicationID: <#your applicationID#>)
    
    // create the OTP observer
    let otpObserver = OTPObserver(settingsParameters: settingsParameters)
    
    // register the observer on the URL session
    sapURLSession.register(otpObserver)
    
    // start to create requests
    
    
    See more

    Declaration

    Swift

    open class OTPObserver
    extension OTPObserver: SAPURLSessionObserving
  • The use of this component is the SDK-suggested way of implementing SAML authentication in the application. The SAMLObserver intercepts requests provided by SAPURLSession and looks for SAML challenge indicating HTTP responses. Upon detecting a SAML challenge, it uses its SAMLAuthenticator to authenticate and resend the original request when the authentication is successful. The caller does not notice anything from the authentication flow.

    Example use:

    // create or acquire the SAPURLSession instance
    let sapURLSession = SAPURLSession()
    
    // perform other steps to initialize the session and the application
    
    // create the SAPcpms settings parameter
    let settingsParameters = SAPcpmsSettingsParameters(backendURL: <#your backendURL#>, applicationID: <#your applicationID#>)
    
    // create the SAML observer
    let samlObserver = SAMLObserver(settingsParameters: settingsParameters)
    
    // register the observer on the URL session
    sapURLSession.register(samlObserver)
    
    // start to create requests
    
    
    See more

    Declaration

    Swift

    open class SAMLObserver
    extension SAMLObserver: SAPURLSessionObserving
  • Listens to authentication challenges using the SAPURLSessionObserving didReceive challenge method. In case an Identity needed the observer calls its IdentityStore to get the Identity. In case there is no certificate the Task will be called by resend which stop the current request and restarts it. During the initialization of the request the UserIdentityObtaining is called to obtain a new Identity.

    See more

    Declaration

    Swift

    open class UserIdentityObserver
    extension UserIdentityObserver: SAPURLSessionObserving
  • The OAuth2Authenticator provides OAuth authentication and authorization functionality to your project and allows authentication of users without intercepting any secure workflows.

    It is rare for a developer to access the OAuth2Authenticator directly — generally, the OAuth2Observer should be used. This component supports:

    Sample code to assemble the authenticator can be found on the initializer’s API doc.

    This sample code demonstrates an authentication flow:

    authenticator.authenticate { token, error in
        if let error = error {
            // If there was an error during the authentication flow then the error can be handled here.
            // Request towards OAuth 2 protected resources will fail without a successful OAuth2 authentication and token acquisition.
            return
        }
        // When the error property is nil that means the OAuth 2 authentication was successful and a OAuth 2 token is acquired.
        // Store the acquired OAuth 2 token and add its access token to all HTTP request directed to OAuth 2 protected resources.
    }
    

    This sample code demonstrates a refresh flow:

    authenticator.refresh(token: expiredToken) { token, error in
        if let error = error {
            // If there was an error during the authentication flow then the error can be handled here.
            // Request towards OAuth 2 protected resources will fail without a successful OAuth2 authentication and token acquisition.
            return
        }
        // When the error property is nil that means the OAuth 2 authentication was successful and a OAuth 2 token is acquired.
        // Store the acquired OAuth 2 token and add its access token to all HTTP request directed to OAuth 2 protected resources.
    }
    
    See more

    Declaration

    Swift

    public class OAuth2Authenticator : OAuth2Authentication
  • The OTPAuthenticator component provides an API to conduct OTP authentication using a web view. By default the OTPAuthenticator will present a default ViewController which contains a web view to perform authentication. This can be replaced by a custom implementation of the WKWebViewPresenting protocol.

    ## This class is for advanced usage only! The SDK preferred way of implementing OTP authentication is the use of the OTPObserver. The direct usage or instantiation of this class is required only when:

    • the authentication is not against SAPcpms, therefore a custom authorization endpoint and finish endpoint URL is given
    • the authentication and network request has to be handled seperatly

    Example of instantiating OTPAuthenticator with custom URLs:

     let otpParameters = OTPParameters(authorizationEndpointURL: <#your authorizationEndpointURL#>, finishEndpointURL: <#your finishEndpointURL#>)
    
     let authenticator = OTPAuthenticator(otpParameters: otpParameters)
    

    Example of authenticating with custom OTPAuthenticator:

     authenticator.authenticate { error in
         if let error = error {
             // If there was an error during the authentication process (web view presentation, or network related), it can be handled here.
             return
         }
         // If there was no error (error is `nil`) then the authentication was successful and the following requests to this endpoint should not encounter OTP challenges.
     }
    
    See more

    Declaration

    Swift

    public class OTPAuthenticator : AppDelegateObserving
  • The SAMLAuthenticator component provides an API to conduct SAML authentication using a web view. Currently only the WKWebView is supported. By default the SAMLAuthenticator will present a default ViewController which contains a web view to perform authentication. This can be replaced by a custom implementation of the WKWebViewPresenting protocol.

    ## This class is for advanced usage only! The SDK preferred way of implementing SAML authentication is the use of the SAMLObserver. The direct usage or instantiation of this class is required only when:

    • the authentication is not against SAPcpms, therefore a custom authorization endpoint and finish endpoint URL is given
    • the authentication and network request has to be handled seperatly

    Example of instantiating SAMLAuthenticator with custom URLs:

     let samlAuthenticationParameters = SAMLAuthenticationParameters(authorizationEndpointURL: <#your authorizationEndpointURL#>, finishEndpointURL: <#your finishEndpointURL#>)
    
     let authenticator = SAMLAuthenticator(authenticationParameters: samlAuthenticationParameters)
    

    Example of authenticating with custom SAMLAuthenticator:

     authenticator.authenticate { error in
         if let error = error {
             // If there was an error during the authentication process (web view presentation, or network related), it can be handled here.
             return
         }
         // If there was no error (error is `nil`) then the authentication was successful and the following requests to this endpoint should not encounter SAML challenges.
     }
    
    See more

    Declaration

    Swift

    public class SAMLAuthenticator : SAMLAuthentication
  • Protocol to get the credential from the user

    See more

    Declaration

    Swift

    public protocol BasicCredentialDiscovery : AnyObject
  • Default implementation of BasicCredentialDiscovery

    See more

    Declaration

    Swift

    public class DefaultBasicCredentialDiscovery : BasicCredentialDiscovery
  • Component to retrieve a User certificate from the device

    See more

    Declaration

    Swift

    public class PKCS12UserIdentityDiscovery : UserIdentityObtaining
  • Component to retrieve a User certificate from Discovery Service

    See more

    Declaration

    Swift

    @available(iOSApplicationExtension, unavailable)
    public class SAPcpmsUserIdentityDiscovery : UserIdentityObtaining
  • Component to retrieve a User certificate from Secure Login Server

    See more

    Declaration

    Swift

    public class SLSUserIdentityDiscovery : UserIdentityObtaining
  • Default implementation for the BasicCredential.

    See more

    Declaration

    Swift

    open class BasicCredentialStorage : BasicCredentialStoring
  • Default implementation for the OAuth2TokenStore.

    See more

    Declaration

    Swift

    open class OAuth2TokenStorage : OAuth2TokenStore
    extension OAuth2TokenStorage: OAuth2TokenStoreUserInfoTransforming
  • Default implementation for the UserIdentityStoring.

    See more

    Declaration

    Swift

    open class UserIdentityStorage : UserIdentityStoring
  • Defines an API capable of reacting to authentication results.

    See more

    Declaration

    Swift

    public protocol AuthenticationHandling : AnyObject
  • Storing protocol for credential

    See more

    Declaration

    Swift

    public protocol BasicCredentialStoring : AnyObject
  • The OAuth2Authentication provides an API to add OAuth authentication and authorization functionality to your project and allows authentication of users without intercepting any secure workflows.

    See more

    Declaration

    Swift

    public protocol OAuth2Authentication
  • Defines a protocol which is capable of storing an OAuth2Token.

    See more

    Declaration

    Swift

    public protocol OAuth2TokenStore
  • The SAMLAuthentication protocol defines an API to conduct SAML authentication.

    See more

    Declaration

    Swift

    public protocol SAMLAuthentication
  • Implementers will be notified when the authenticated user changes during runtime if a new authentication is forced by the server and the user authenticates with credentials ends up on a different user Id

    See more

    Declaration

    Swift

    public protocol AuthenticationDelegate : AnyObject
  • Delegate to communicate with the client

    See more

    Declaration

    Swift

    public protocol SLSLoginInputDelegate : AnyObject
  • The implementer has to call back with a PKCS#12 identity data using no password

    See more

    Declaration

    Swift

    public protocol UserIdentityObtaining
  • Protocol for describe how the certificate should store the identity and handle the stored ones

    See more

    Declaration

    Swift

    public protocol UserIdentityStoring : AnyObject
  • The SAPcpmsAuthenticationManager implements the AuthenticationHandling protocol, thus capable of being injected into the adequate authentication observers for result handling. Stores and compares users based on the newly acquired credentials through the SAPcpmsUserRoles component. SAPcpmsAuthenticationManager calls the configured authentication delegates to notify appropriate events. Internal authentication delegate is used internally by the framework and user authentication delegate, invoked subsequently (if present), is the delegate configured by the developer.

    See more

    Declaration

    Swift

    public class SAPcpmsAuthenticationManager : AuthenticationHandling
  • Username and password of the basic credential

    See more

    Declaration

    Swift

    public struct BasicCredential : Codable
  • A data container that holds all relevant output information that are common for an OAuth2 token across all grants.

    See more

    Declaration

    Swift

    public struct OAuth2Token
    extension OAuth2Token: Equatable
    extension OAuth2Token: Codable
  • Struct with the requested information addressed to the user

    See more

    Declaration

    Swift

    public struct SLSLoginInput
  • One unit of information that the client should ask from the user

    See more

    Declaration

    Swift

    public struct SLSLoginInputField
  • Struct for provided input values

    See more

    Declaration

    Swift

    public struct SLSLoginInputFieldValue
  • A wrapper for the expected input parameters for the OAuth2 Authorization Code Grant.

    See more

    Declaration

    Swift

    public struct OAuth2AuthenticationParameters
    extension OAuth2AuthenticationParameters: DiscoveryServiceConfigurable
  • A wrapper for the expected input parameters for the OAuth2 Client Credentials Grant.

    See more

    Declaration

    Swift

    public struct OAuth2ClientCredentialsAuthenticationParameters
    extension OAuth2ClientCredentialsAuthenticationParameters: DiscoveryServiceConfigurable
  • This struct contains the necessary parameters to conduct a OTP authentication using a web view. This is used with the OTPAuthenticator class.

    See more

    Declaration

    Swift

    public struct OTPParameters
    extension OTPParameters: DiscoveryServiceConfigurable
  • This struct contains the necessary parameters to conduct a SAML authentication using a web view. This is used with the SAMLAuthenticator class.

    See more

    Declaration

    Swift

    public struct SAMLAuthenticationParameters
    extension SAMLAuthenticationParameters: DiscoveryServiceConfigurable
  • Parameters to get the certificate form the Discovery Service

    See more

    Declaration

    Swift

    public struct SAPcpmsUserIdentityConfigurationParameters
  • Input parameters to be able to connect to the SLS server

    See more

    Declaration

    Swift

    public struct SLSConfigurationParameters
    extension SLSConfigurationParameters: DiscoveryServiceConfigurable
  • Errors for BasicCredential module

    See more

    Declaration

    Swift

    public enum AuthenticationObserverError : Error
    extension AuthenticationObserverError: SAPError
  • Errors for BasicCredentialDiscovery module

    See more

    Declaration

    Swift

    public enum BasicCredentialDiscoveryError : Error
    extension BasicCredentialDiscoveryError: SAPError
  • Possible errors that can occur during configuration parsing.

    See more

    Declaration

    Swift

    public enum ConfigurationError : Error
    extension ConfigurationError: SAPError
  • Enumeration to describe the errors of the OAuth2 authentication

    See more

    Declaration

    Swift

    public enum OAuth2Error : Error
    extension OAuth2Error: SAPError
  • Struct to detail the server responsed error

    See more

    Declaration

    Swift

    public struct OAuth2ServerError
    extension OAuth2ServerError: SAPError
  • Enumeration to describe the errors of the OTP authentication.

    See more

    Declaration

    Swift

    public enum OTPError : Error
    extension OTPError: SAPError
  • Enumeration to describe the errors of the SAML authentication.

    See more

    Declaration

    Swift

    public enum SAMLError : Error
    extension SAMLError: SAPError
  • Set of errors the SAPcpmsAuthenticationManager could encounter.

    • userSwitch: The acquired new credentials belong to a different user than the initial one
    See more

    Declaration

    Swift

    public enum SAPcpmsAuthenticationManagerError : Error
    extension SAPcpmsAuthenticationManagerError: SAPError
  • Errors for SAPcpmsUserIdentityDiscovery module

    See more

    Declaration

    Swift

    public enum SAPcpmsUserIdentityDiscoveryError : Error
    extension SAPcpmsUserIdentityDiscoveryError: SAPError
  • Errors for SLS module

    See more

    Declaration

    Swift

    public enum SLSUserIdentityDiscoveryError : Error
    extension SLSUserIdentityDiscoveryError: SAPError
  • Errors for UserIdentityDiscovery module

    See more

    Declaration

    Swift

    public enum UserIdentityObserverError : Error
    extension UserIdentityObserverError: SAPError