SAPcpmsUserIdentityDiscovery

public class SAPcpmsUserIdentityDiscovery : UserIdentityObtaining

SAPcpms User Identity Discovery


General flow obtaining user identity

The discovery of the certificate works automatically using the UserIdentityObserver that is registered to SAPURLSession. The UserIdentityObserver uses the SAPcpmsUserIdentityDiscovery to obtain the certificate.

  1. The application initiates a request to the resource server which requires a user identity resulting in a challenge in the SAPURLSession.
  2. The UserIdentityObserver calls the application using the UserIdentityStoring protocol. If there is no valid identity, the observer calls the SAPcpmsUserIdentityDiscovery to obtain a certificate.
  3. The SAPcpmsUserIdentityDiscovery initiates a request to the Certificate Discovery service to get the certificate attributes which triggers the OAuth authentication. After a successful authentication, the certificate parameters are downloaded.
  4. The SAPcpmsUserIdentityDiscovery generates a private key to sign the Certificate Signing Request (CSR) and to create the identity later.
  5. These parameters are used to create a CSR, which is sent to the Certificate Discovery which creates the certificate.
  6. The SAPcpmsUserIdentityDiscovery creates a SecIdentity using this certificate and the generated private key.
  7. The identity is transformed to a PKCS #12 Data which will be passed to the caller as the result
  8. This Data should be stored securely by the customer and provided later if the component needs an identity. For this purpose the UserIdentityStoring protocol can be used.
  9. The original request to resource server restarts automatically. So the next time the server challenges for identity, it will be accessible.

Usage

Implementing UserIdentityStoring protocol

The UserIdentityObserver uses this protocol to store and retrieve the identity. The implementer has to store the identity in a secure way. The identity received by the SAPcpmsUserIdentityDiscovery. The URL can be used to distinguish identities if the application uses more resource servers.

func store(identity: Data, for url: URL?) throws -> Void {
    // save the identity to a secure storage
}

func identity(for url: URL?) throws -> Data? {
    // return the identity from the secure storage
}

func delete(for url: URL?) throws {
    // delete the identity from the secure storage
}

UserIdentityObserver initialization

Convenience initializer with configuration from Discovery Service

This is the recommended initialization. The first certificateDiscoveryConfiguration parameters is a dictionary retrieved from ConfigurationProvider, that contains the user identity configuration and the OAuth2 authentication parameters.

let userIdentityDiscoveryObserver = UserIdentityObserver(certificateDiscoveryConfiguration <#configurationDictionary#>, identityStore: <#self or other `UserIdentityStoring` implementation#>)
urlSessionForResourceURL.register(userIdentityDiscoveryObserver)

Note:

  • The observer in this case automatically initializes the SAPcpmsUserIdentityDiscovery, the OAuth2Authenticator, the OAuth2Observer and the SAPURLSession to communicate with the Discovery Service
  • The OAuth2Authenticator uses SFSafariViewController by default. Please don’t forget to implement this method in the AppDelegate:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    OAuth2Authenticator.application(app, open: url, options: options)
    return true
}
  • The structure in the dictionary should follow this JSON structure:
{
  "com.sap.mobilesecure.certificateService.attributesEndpoint":"",
  "com.sap.mobilesecure.certificateService.requestEndpoint":"",
  "com.sap.mobilesecure.certificateService.retireEndpoint":"",
  "com.sap.mobilesecure.certificateService.publicKeyPinSet":[],
  "com.sap.mobilesecure.certificateService.authType":{
    "type":"oauth",
    "authorizationEndpoint":"",
    "tokenEndpoint":"",
    "client_id":"",
    "redirect_uri":""
  }
}

Convenience initializer if the configuration comes from other sources

let configurationParameters = SAPcpmsUserIdentityConfigurationParameters(attributesEndpoint: <#URL#>, requestEndpoint: <#URL#>, retireEndpoint: <#URL#>, publicKeyPinSet: <#[String]#>)
let oAuth2AuthenticationParameters = OAuth2AuthenticationParameters(authorizationEndpointURL: <#URL#>, clientID: <#String#>, redirectURL: <#URL#>, tokenEndpointURL: <#URL#>, requestingScopes: <#Set[String]#>)
let userIdentityDiscoveryObserver = UserIdentityObserver(userIdentityConfigurationParameters: <#SAPcpmsUserIdentityConfigurationParameters#>, oAuth2AuthenticationParameters: <#OAuth2AuthenticationParameters#>, identityStore: <#UserIdentityStoring#>)
urlSessionForResourceURL.register(userIdentityDiscoveryObserver)

Note: The observer in this case automatically initializes the SAPcpmsUserIdentityDiscovery, the OAuth2Authenticator, the OAuth2Observer and the SAPURLSession for the OAuth2 authentication

Most customizable option

This type of initialization gives more control to the application developer if special customization. In this case all the necessary classes has to be initialised.

Note: Implement OAuth2TokenStore OAuth2TokenStore Example

Note: Initialize a SAPURLSession (E.g.: urlSessionForUserIdentityDiscovery) with OAuth2Observer used by SAPcpmsUserIdentityDiscovery according to OAuth2Observer

The SAPcpmsUserIdentityDiscovery can obtain the certificate and read the user identity from it.

Initialize a SAPcpmsUserIdentityDiscovery and a UserIdentityObserver:

let userIdentityDiscovery = SAPcpmsUserIdentityDiscovery(certificateDiscoveryParameters: configurationParameters, sapURLSession: <#urlSessionForUserIdentityDiscovery#>)
let userIdentityDiscoveryObserver = UserIdentityObserver(userIdentityDiscovery: userIdentityDiscovery, identityStore: <#Identity Store implementation#>)
urlSessionForResourceURL.register(userIdentityDiscoveryObserver)

Start request to Resource URL

let request = URLRequest(url: <#resourceURL#>)
let dataTask = urlSessionForResourceURL.dataTask(with: request) { data, response, error in
    // Handle the error and the response
}
dataTask.resume()

Component to retrieve a User certificate from Discovery Service

  • A data container that holds all relevant output information that are common for an OAuth2 token across all grants.

    Declaration

    Swift

    public var oauthToken: String?
  • Convenience initializer of SAPcpmsUserIdentityDiscovery

    Declaration

    Swift

    public convenience init(certificateDiscoveryParameters: SAPcpmsUserIdentityConfigurationParameters, oAuth2AuthenticationParameters: OAuth2AuthenticationParameters)

    Parameters

    certificateDiscoveryParameters

    parameters to get the certificate in scope of the SAPcpmsUserIdentityDiscovery

    oAuth2AuthenticationParameters

    parameters to the OAuth2 authentication process

  • Initializer of SAPcpmsUserIdentityDiscovery

    Declaration

    Swift

    public init(certificateDiscoveryParameters: SAPcpmsUserIdentityConfigurationParameters, sapURLSession: SAPURLSession)

    Parameters

    certificateDiscoveryParameters

    parameters to get the certificate in scope of the SAPcpmsUserIdentityDiscovery

    urlSession

    URL session to get the Certificate Attributes and the Certificate. Keeped with strong reference.

  • Obtain the user identity. The process covers the getting of certificate attributes, create CSR, and getting the certificate.

    Declaration

    Swift

    public func obtainUserIdentity(completionHandler: @escaping (Data?, Error?) -> Void)

    Parameters

    completionHandler

    Result with Data and Error. The Data is the PKCS #12 formatted SecIdentity that received from the server.