SAP Customer Data Cloud Positions

Push Authentication

Skip to end of metadata
Go to start of metadata

Overview

Push Authentication passwordless login is part of the SAP Customer Data Cloud Customer Identity offering. It allows your customers to authenticate on their mobile phones, by confirming a push notification, instead of using their password to log in.

The Push Authentication flow is as follows: 

  1. Customer registers to your website with email or username, creates a password. 
  2. Customer logs into your app on their mobile phone, with the same identifier (email or username). 
  3. The next time the customer logs in to your website, they can choose whether to authenticate with a password or a push notification. 
  4. If the customer chooses push notification, a notification is sent to their mobile phones. 
  5. After confirming the notification, the user is authenticated on your website. 

Implementation

App Configuration

Before you configure Push Authentication on SAP Customer Data Cloud, you should set up your mobile app on which users register to receive a push notifications. 

In order to add Push Authentication to your application you will need a working push notification/messaging account with Google Firebase. Instructions on how to add Firebase to your Android application can be found here.

Once you have your Firebase up and running, you are able to register your application in the cloud messaging tab of your project settings page. This is used for configuring push notifications in the Customer Data Cloud Policies page, as explained below.

The steps below also include instructions for handling biometric authentication, in case it is enabled on the user's device. 

Biometric data is only used natively by the device's operating system for authentication, and is not stored on SAP Customer Data Cloud servers.

 

 

Android

 Click here for Android push configuration

Auth Library

Push Authentication uses the dedicated Auth 1.0.0 library which can be downloaded with the SDK

To integrate the authentication library within your application make sure that you have successfully integrated the Android SDK v4.+ core library as it is a mandatory dependency for using the new authentication flows.

Add the Auth library archive implementation in your application build.gradle file:

implementation files('libs/gigya-android-auth-1.0.0.aar')

Firebase Registration

Registering your application to receive remote authentication push messages is available using the following implementation steps:

Define the GigyaFirebaseMessagingService in your AndroidManifest.xml file:

If your application already uses FirebaseMessagingService, you will be required to make your service class implementation to extend the GigyaFirebaseMessagingService. This will not break any of your remote messaging flows in any way. Make sure to call the main "super" functions to allow the GigyaFirebaseMessagingService to perform its own logic.

For example:

public class MyCustomMessagingService extends GigyaFirebaseMessagingService {
   
    /*
    * Make sure to call the super function to allow parent logic to remain intact.
    */
    @Override
    public void onNewToken(String newToken) {
        super.onNewToken(newToken);
    }
   
    /*
    * Make sure to call the super function to allow parent logic to remain intact.
    */
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
    }
  
}

Update your AndroidManifest.xml file as follows:

<service
    android:name="com.gigya.android.sdk.push.GigyaFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

In addition, you are required to register the AuthPushReceiver.java class. This class will intercept verification actions that are visible in the incoming remote notifications.

/*
Action names are library specific. If you wish, you are able to override the strings ids but we storgly recommend that you use these to avoid errors.
*/
  
<receiver
    android:name="com.gigya.android.sdk.auth.push.AuthPushReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="@string/gig_auth_action_approve" /> /* "com.gigya.android.sdk.auth.push_approve" */
        <action android:name="@string/gig_auth_action_deny" /> /* "com.gigya.android.sdk.auth.push_deny" */
    </intent-filter>
</receiver>

In order to correctly initialize the library, call the "registerForPushNotification" library function from your entry point activity. This function will query your application settings to make sure that notification permission is enabled for this service. In the case, settings are disabled the SDK will issue a notice dialog.

GigyaAuth.getInstance().registerForPushNotifications(this /* activity context */)

Authentication Flow

Before a user can authenticate with a push notification, they have to be registered on your app (with the standard SAP Customer Data Cloud registration flow) and must have an active session. In addition, to start the Push Authentication flow for a user, their device needs to be registered for this service. Device registration is done by calling the library "registerForAuthPush" method.

GigyaAuth.getInsance().registerForAuthPush(new GigyaCallback<GigyaApiResponse>() {
  
@Override
public void onSuccess(GigyaApiResponse obj) {
    // Device successfully registered.
}
  
@Override
public void onError(GigyaError error) {
    // Error registring device.
}
  
});

Once the device is successfully registered, when the user starts a login process on a separate device (e.g. desktop), the registered mobile device will receive a push notification which they can approve or deny. 

The SDK provides additional customization options for remote messages and the option to use your own customized activity for remote actions (approve/deny). Using a customized action activity is mandatory for supporting push functionality for fingerprint encrypted sessions. A detailed example is provided further down this tutorial.

For customization, use the following method:

GigyaAuth.getInstance().setPushCustomizer(new IGigyaPushCustomizer() {
  
@Override
public Class getCustomActionActivity() {
    return MyCustomActionActivity.class;
}
  
@Override
public int getSmallIcon() {
    return R.drawable.my_custom_tfa_notification_icon;
}
  
/*
* Note: These icons will only display until Android Nougat (api level 25).
*/
@Override
public int getApproveActionIcon() {
    return R.drawable.my_custom_tfa_approve_action_icon_api_25;
}
  
/*
* Note: These icons will only display until Android Nougat (api level 25).
*/
@Override
public int getDenyActionIcon() {
    return R.drawable.my_custom_tfa_deny_action_icon_api_25;
}
  
});

Fingerprint Encrypted Sessions

Push TFA actions depend on the user having a session. Therefore, when the user's session is fingerprint-encrypted, the user needs to authenticate with their fingerprint, to complete the push notification authentication flow.

The Android TFA library and the Android Biometric libraries are two independent libraries.

 

When using biometric session encryption, your TFA notification will not contain Approve/Deny buttons. Action handing will be done via notification click using an extension of the PushTFAActivity.class .

 

To achieve a successful authentication flow, follow these steps:

Step 1

You will need to evaluate the session state when your extension activity starts. If the session is encrypted using the "FINGERPRINT" tag, the user will first need to unlock it, before the notification can be displayed.

Additionally, If the session was previously locked it is recommended to lock it again after the push notification approval, to avoid irregular behaviours.

The following sample combines the biometric support and the push TFA feature:

class BiometricPushTFAActivity : PushTFAActivity() {
  
    // Helper state for locking back the session if was previously unlocked.
    private var shouldLockSessionOnApproval: Boolean = false
  
    // Referencing the biometric library.
    private val biometric: GigyaBiometric = GigyaBiometric.getInstance()
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
  
        evaluateSessionState()
    }
      
    // Override and return false in order the control when the action alert will show.
    override fun alertOnCreate(): Boolean = false
  
    /**
    * Evaluate the current session encryption state.
    */
    private fun evaluateSessionState() {
        when (_tfaLib.sessionEncryption == "FINGERPRINT") {
            true -> {
                if (!biometric.isAvailable) {
                    GigyaLogger.error("BiometricPushTFAActivity",
                            "Session is FINGERPRINT locked but biometric support is not available")
                    finish()
                    return
                }
                if (!biometric.isLocked) {
                    showActionAlert()
                    return
                }
                biometric.unlock(
                        this,
                        GigyaPromptInfo(
                                getString(R.string.tfa_biometric_locked_session_title),
                                getString(R.string.tfa_biometric_locked_session_subtitle),
                                getString(R.string.tfa_biometric_locked_session_description)
                        ),
                        object : IGigyaBiometricCallback {
                            override fun onBiometricOperationSuccess(action: GigyaBiometric.Action) {
                                GigyaLogger.debug("BiometricPushTFAActivity", "onBiometricOperationSuccess: Okay to approve push action")
                                shouldLockSessionOnApproval = true
                                showActionAlert()
                            }
  
                            override fun onBiometricOperationFailed(reason: String?) {
                                GigyaLogger.debug("BiometricPushTFAActivity", "onBiometricOperationFailed: - $reason - Available for retry")
  
                            }
  
                            override fun onBiometricOperationCanceled() {
                                GigyaLogger.debug("BiometricPushTFAActivity", "onBiometricOperationFailed: Push action is lost. Will call onDeny")
                                onDeny()
                            }
                        }
                )
            }
            false -> {
                showActionAlert()
            }
        }
    }
  
    /**
    * Overriding the approval action.
    */
    override fun onApprove(extras: Bundle?) {
        super.onApprove(extras)
        if (shouldLockSessionOnApproval) {
            shouldLockSessionOnApproval = false
            if (biometric.isAvailable) {
                biometric.lock(object : IGigyaBiometricOperationCallback {
                    override fun onBiometricOperationSuccess(action: GigyaBiometric.Action) {
                        GigyaLogger.debug("BiometricPushTFAActivity", "onBiometricOperationSuccess: ")
                    }
  
                    override fun onBiometricOperationFailed(reason: String?) {
                     GigyaLogger.error("BiometricPushTFAActivity ", "onBiometricOperationFailed: Session will remain unlocked")
                    }
                  
                })
            }
        }
    }
  
}

Step 2: Create a Custom Extension Class for the GigyaFirebaseMessagingService Class

An extension service class is needed to define your custom TFA activity.

class GigyaFirebaseMessagingExt : GigyaFirebaseMessagingService() {
  
    override fun getCustomActionActivity(): Class<*> {
        return BiometricPushTFAActivity::class.java
    }
}

Don't forget to correctly declare your extension classes in your AndroidManifest.xml.

Example taken from the provided sample application:

<activity
    android:name=".ui.BiometricPushTFAActivity"
    android:excludeFromRecents="true"
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:theme="@style/Theme.AppCompat.Translucent" />
   
<service
    android:name="GigyaFirebaseMessagingExt"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>


Swift

 Click here for Swift push configuration

Auth Library

Push Authentication uses the dedicated Auth 1.0.0 library which can be downloaded with the SDK.

To integrate the authentication library within your application make sure that you have successfully integrated the Swift core library as it is a mandatory dependency for using the new authentication flows.

To use Push Authentication, add the following line to your AppDelegate.swift:

GigyaAuth.shared.registerForRemoteNotifications()

Add the Gigya Messaging Service

  1. Enable remote notifications: In your app project, go to your project target and open Capabilities > Background Modes. Make sure Remote notifications is enabled.
  2. Allow Firebase to send foreground notifications: After you called FirebaseApp.configure() add the follow line:

    FirebaseApp.configure()
    // Add this line
    Messaging.messaging().shouldEstablishDirectChannel = true
  3. Add Firebase delegate: The Gigya server requires receiving the push token to send push notifications to your user's devices. To do so, add the following to your AppDelegate.swift:

    // MessagingDelegate implementation as shown in Firebase documentation.
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("Firebase registration token: \(fcmToken)")
        let dataDict:[String: String] = ["token": fcmToken]
    
        NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
    
        Gigya.sharedInstance().updatePushToken(key: fcmToken)
    }
    
    // Foreground notification receive
    func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
        Gigya.sharedInstance().foregroundNotification(with: remoteMessage.appData)
    }
  4. Handling push notifications: to let the SDK handle incoming push notifications, add the following to your AppDelegate.swift:

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // Enable Gigya's handling of the notification.
        Gigya.sharedInstance().receivePush(userInfo: userInfo, completion: completionHandler)
    }
  5. Notification interaction: Gigya's notifications require action confirmations (end-user approving or denying the push opt-in). To open the actions alert confirmation, add the following to your AppDelegate.swift.

    @available(iOS 10.0, *)
    extension AppDelegate: UNUserNotificationCenterDelegate {
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            // tap on notification interaction
            Gigya.sharedInstance().verifyPush(with: response)
        }
    }

Authentication Flow

Before a user can authenticate with a push notification, they have to be registered on your app (with the standard SAP Customer Data Cloud registration flow) and must have an active session. In addition, to start the Push Authentication flow for a user, their device needs to be registered for this service. Device registration is done by calling the library "registerForAuthPush" method: 

GigyaAuth.shared.registerForAuthPush { result in
    switch result {
    case .success:
         // Register to login by Push has been completed.
    case .failure(let error):
        // Handle error.
    }
}

Once the device is successfully registered, when the user starts a login process on a separate device (e.g. desktop), the registered mobile device will receive a push notification which they can approve or deny:

 

Biometric Encrypted Sessions

Push TFA actions depend on the user having a session. Therefore, when the user's session is encrypted via fingerprint (touch ID) or face ID, the user needs to pass biometric authentication, to complete the push notification authentication flow.

To enable FaceID on an encrypted device, include the following key to your Info.plist file.

 

NSFaceIDUsageDescription = (String) "Your custom message"

To set a custom text for a Touch ID prompt, include the following key:

 

GigyaTouchIDMessage = (String) "Your custom message" (default = "Please authenticate to proceed”).

 

 

 

Policies

To enable Push Authorization on the SAP Customer Data Cloud Console:

  1. Open the Firebase console. select your project and open Project settings
  2. Select the Cloud Messaging tab and copy your Server key.
  3. Enable Push Authentication for your site on the Policies page in the Console
    • Password authentication is enabled by default. 
    • Enable Push Notification, and enter your Firebase Server key. 
  4. Save your settings. 


Screen-Sets

The Push Authentication flow includes the following screens, in the RegistrationLogin screen-set. 

To enable Push Authentication for end users, create a new screen-set collection, or add the new screens to an existing collection. 

 

 

 

  • Passwordless Login: Includes a login identifier field (currently supports email or username) which the user submits. 

    • When no authentication methods are associated with their account, the next screen is Auth Methods

    • If they do have an authentication method, the relevant Password Auth or Push Notification Auth screen opens. If they have both methods, the latest authentication method is used.

  • Auth Methods: If no authentication method is saved to the user's account, they select the method on this screen. 

  • Password Auth: If the user chose to authenticate with a password, they can enter it here. 

  • Push Notification Auth: If the user chose Push Notfications, this screen opens and checks periodically to see if the user has approved the push notification on their app. Once the user approves, this screen disappears and the user is logged in. For the full API flow, see accounts.auth.push.sendVerification.


 

Additional Information

  • No labels