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:
- authorizationEndpointURL: https://www.myhost.com/SAMLAuthLauncher
- finishEndpointURL: https://www.myhost.com/SAMLAuthLauncher?finishEndpointParam=someUnusedValue
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.
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.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.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.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.
- 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.
- After the OAuth 2 challenge is detected, the authentication (or refresh) must take place.
Notes:
- You can find the URLs on the given SAP Mobile Services page, under your application’s OAuth settings.
- The obtained
OAuth2Token
is stored on theOAuth2TokenStore
. - For details on how to set up and use the store, see: Example of OAuth2 token store.
Authorization Code Flow
Authentication
- 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.
- 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
- 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. - The client issues a native POST request to the tokenEndpointURL, containing the authorization code.
- The expected response of this request is a JSON payload containing
access_token
,refresh_token
,token_type
,expires_in
andscope
, which are internally used to create theOAuth2Token
.6. After successful authentication, the original request resent. - 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:
- The client issues a native POST request to the tokenEndpointURL, containing the refresh token property.
- The response of this request is a serialized token which is internally used to create the
OAuth2Token
. - After a successful refresh, the original request resent.
Client Credentials
Authentication
- The authentication happens in a background process.
- The URL expected by the server contains multiple parameters which is assigned during runtime. The included parameters are (See OAuth2ClientCredentialsAuthenticationParameters for details):
- requestingScopes
- The client issues a native POST request to the tokenEndpointURL, containing the authentication parameters.
- The expected response of this request is a JSON payload containing
access_token
,token_type
,expires_in
andscope
, which are internally used to create theOAuth2Token
. - 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:
- authorizationEndpointURL: https://www.myhost.com/mobileservices/OTPForm?redirecttooriginalurl=false
- finishEndpointURL: https://www.myhost.com/mobileservices/OTPForm?finished=true
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.
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.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.
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.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 moreDeclaration
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 anOAuth2Authentication
instance to authenticate and to refresh tokens. For token storing theOAuth2TokenStore
is used.This component supports:
Authorization Code
grant flow with theBearer token
type.Client Credentials
grant flow.
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
See moreOAuth2TokenStore
protocol, therefore it can passself
as thetokenStore
. It is also assumed to have asapURLSession
which is an instance ofSAPURLSession
.Declaration
-
The use of this component is the SDK-suggested way of implementing OTP authentication in the application. The
OTPObserver
intercepts requests provided bySAPURLSession
and looks for OTP challenge indicating HTTP responses. Upon detecting an OTP challenge, it uses itsOTPAuthenticator
to authenticate and resend the original request when the authentication is successful. The caller does not notice anything from the authentication flow.Example use:
See more// 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
Declaration
-
The use of this component is the SDK-suggested way of implementing SAML authentication in the application. The
SAMLObserver
intercepts requests provided bySAPURLSession
and looks for SAML challenge indicating HTTP responses. Upon detecting a SAML challenge, it uses itsSAMLAuthenticator
to authenticate and resend the original request when the authentication is successful. The caller does not notice anything from the authentication flow.Example use:
See more// 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
Declaration
-
Listens to authentication challenges using the
See moreSAPURLSessionObserving
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 theUserIdentityObtaining
is called to obtain a new Identity.Declaration
-
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:
Authorization Code
grant flow with theBearer token
type.Client Credentials
grant flow.
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:
See moreauthenticator.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. }
Declaration
Swift
public class OAuth2Authenticator : OAuth2Authentication
-
The
OTPAuthenticator
component provides an API to conduct OTP authentication using a web view. By default theOTPAuthenticator
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:
See moreauthenticator.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. }
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 theSAMLAuthenticator
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:
See moreauthenticator.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. }
Declaration
Swift
public class SAMLAuthenticator : SAMLAuthentication
-
Protocol to get the credential from the user
See moreDeclaration
Swift
public protocol BasicCredentialDiscovery : AnyObject
-
Default implementation of
See moreBasicCredentialDiscovery
Declaration
Swift
public class DefaultBasicCredentialDiscovery : BasicCredentialDiscovery
-
Component to retrieve a User certificate from the device
See moreDeclaration
Swift
public class PKCS12UserIdentityDiscovery : UserIdentityObtaining
-
Component to retrieve a User certificate from Secure Login Server
See moreDeclaration
Swift
public class SLSUserIdentityDiscovery : UserIdentityObtaining
-
Default implementation for the
See moreBasicCredential
.Declaration
Swift
open class BasicCredentialStorage : BasicCredentialStoring
-
Default implementation for the
See moreOAuth2TokenStore
.Declaration
Swift
open class OAuth2TokenStorage : OAuth2TokenStore
extension OAuth2TokenStorage: OAuth2TokenStoreUserInfoTransforming
-
Default implementation for the
See moreUserIdentityStoring
.Declaration
Swift
open class UserIdentityStorage : UserIdentityStoring
-
Defines an API capable of reacting to authentication results.
See moreDeclaration
Swift
public protocol AuthenticationHandling : AnyObject
-
Storing protocol for credential
See moreDeclaration
Swift
public protocol BasicCredentialStoring : AnyObject
-
The
See moreOAuth2Authentication
provides an API to add OAuth authentication and authorization functionality to your project and allows authentication of users without intercepting any secure workflows.Declaration
Swift
public protocol OAuth2Authentication
-
Defines a protocol which is capable of storing an
See moreOAuth2Token
.Declaration
Swift
public protocol OAuth2TokenStore
-
The
See moreSAMLAuthentication
protocol defines an API to conduct SAML authentication.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 moreDeclaration
Swift
public protocol AuthenticationDelegate : AnyObject
-
Delegate to communicate with the client
See moreDeclaration
Swift
public protocol SLSLoginInputDelegate : AnyObject
-
The implementer has to call back with a PKCS#12 identity data using no password
See moreDeclaration
Swift
public protocol UserIdentityObtaining
-
Protocol for describe how the certificate should store the identity and handle the stored ones
See moreDeclaration
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 moreDeclaration
Swift
public class SAPcpmsAuthenticationManager : AuthenticationHandling
-
Username and password of the basic credential
See moreDeclaration
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 moreDeclaration
Swift
public struct OAuth2Token
extension OAuth2Token: Equatable
extension OAuth2Token: Codable
-
Struct with the requested information addressed to the user
See moreDeclaration
Swift
public struct SLSLoginInput
-
One unit of information that the client should ask from the user
See moreDeclaration
Swift
public struct SLSLoginInputField
-
Struct for provided input values
See moreDeclaration
Swift
public struct SLSLoginInputFieldValue
-
A wrapper for the expected input parameters for the OAuth2 Authorization Code Grant.
See moreDeclaration
Swift
public struct OAuth2AuthenticationParameters
extension OAuth2AuthenticationParameters: DiscoveryServiceConfigurable
-
A wrapper for the expected input parameters for the OAuth2 Client Credentials Grant.
See moreDeclaration
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
See moreOTPAuthenticator
class.Declaration
-
This struct contains the necessary parameters to conduct a SAML authentication using a web view. This is used with the
See moreSAMLAuthenticator
class.Declaration
Swift
public struct SAMLAuthenticationParameters
extension SAMLAuthenticationParameters: DiscoveryServiceConfigurable
-
Parameters to get the certificate form the Discovery Service
See moreDeclaration
Swift
public struct SAPcpmsUserIdentityConfigurationParameters
-
Input parameters to be able to connect to the SLS server
See moreDeclaration
Swift
public struct SLSConfigurationParameters
extension SLSConfigurationParameters: DiscoveryServiceConfigurable
-
Errors for BasicCredential module
See moreDeclaration
Swift
public enum AuthenticationObserverError : Error
extension AuthenticationObserverError: SAPError
-
Errors for BasicCredentialDiscovery module
See moreDeclaration
Swift
public enum BasicCredentialDiscoveryError : Error
extension BasicCredentialDiscoveryError: SAPError
-
Possible errors that can occur during configuration parsing.
See moreDeclaration
Swift
public enum ConfigurationError : Error
extension ConfigurationError: SAPError
-
Enumeration to describe the errors of the OAuth2 authentication
See moreDeclaration
Swift
public enum OAuth2Error : Error
extension OAuth2Error: SAPError
-
Struct to detail the server responsed error
See moreDeclaration
Swift
public struct OAuth2ServerError
extension OAuth2ServerError: SAPError
-
Enumeration to describe the errors of the OTP authentication.
See moreDeclaration
Swift
public enum OTPError : Error
extension OTPError: SAPError
-
Enumeration to describe the errors of the SAML authentication.
See moreDeclaration
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
Declaration
Swift
public enum SAPcpmsAuthenticationManagerError : Error
extension SAPcpmsAuthenticationManagerError: SAPError
-
Errors for SAPcpmsUserIdentityDiscovery module
See moreDeclaration
Swift
public enum SAPcpmsUserIdentityDiscoveryError : Error
extension SAPcpmsUserIdentityDiscoveryError: SAPError
-
Errors for SLS module
See moreDeclaration
Swift
public enum SLSUserIdentityDiscoveryError : Error
extension SLSUserIdentityDiscoveryError: SAPError
-
Errors for UserIdentityDiscovery module
See moreDeclaration
Swift
public enum UserIdentityObserverError : Error
extension UserIdentityObserverError: SAPError