Client Service - Open ID Connect
Problem
Currently, there are no security mechanisms in communication between Mobile SDK and Client service API when registering an identified user (user logs in within a mobile app). This makes it possible for any person to impersonate whoever they want by registering a user with a contact field ID and contact field value of the victim. Following that, they could send events which do not come from the original user.
Proposal
It was proposed to use Open ID Connect to solve this issue. Open ID Connect is a well-established protocol, and customers could anyhow already use is in their apps for their own authentication purposes. At first, we would support a fixed set of Open ID providers, which we could later make configurable in the UI. Also, we will allow customers to enter a transition period - by configuring it in the UI - in which they will be able to allow both current no-authentication flow, and new Open ID Connect flow to be valid at the same time. Once sufficient number of users has migrated to the new app version, they will be able to disallow the no-authentication flow.
Workflow
-
Client app shows the login screen with possibly several supported Open ID providers (e.g. Facebook, Google, Slack, GitHub). User selects a provider, enters login credentials, and submits the form.
-
Client sends the OAuth 2.0 request to the provider including credentials, client ID, redirect URL, grant scope, nonce, and other optional parameters.
-
Open ID Provider validates the credentials, authenticates the user, and sends the 302 Redirect to the provided redirect URL, back to the client. The redirect URL includes auth code as a query parameter.
-
Client follows the redirect URL to the customer’s web service.
-
Web services uses the auth code from the request, and requests the tokens (ID token, and access token) from the Open ID provider, by additionally providing a client secret.
-
Open ID provider validates the request, generates ID token, and access token and sends it back to the customer’s web service.
-
Customer’s web service sends both tokens back to the client, or just an ID token (if access token is not needed directly on the client). ID token will then be used to authenticate the client with the customer’s web services.
-
Client stores the token(s) in the local datastore. Client sends the request to Client service to link to an identified user, providing the ID token in the body.
-
Client service validates the ID token’s data according to the specification. It then checks the
issproperty to find out the Open ID provider, and fetches its Open ID public key. -
Open ID provider returns the public key. Client service caches the key according to the response cache headers.
-
Client service validates the ID token’s signature, and extracts the unique id of the contact from the Open-ID provider or the authenticated email based on the
clientFieldIdspecified. -
Client service generates and returns contact token and refresh token.
API Changes
Open ID token
Client service will add support for an alternative body payload of the /apps/:app-code/client/contact endpoint allowing the openIdToken to use used instead of the contactFieldValue. Client service will read and cache the app’s auth configuration, and based on it will allow setting the contact by:
-
current no-authentication flow,
-
Open ID token, or
-
either of them (whichever succeeds).
Contact token & refresh token
We can continue generating contact token and refresh token the same manner, and validating their signatures on Client service backend.
We should not start rejecting existing refresh tokens once customers switch to Open ID flow exclusively. Current Mobile SDK versions do not expect refresh tokens to ever expire and be rejected. Even if new Mobile SDK version changes that behavior, rejecting a refresh token would mean that we need a mobile user to log in again into the customer’s app. Forcing the logout/login of the by the Marketing SDK could be controversial. We should verify it with the customers.
Using E-mail as contact-identifier
Since the email included in the id-token is authenticated by the Open-ID provider it would be possible for us to use it for matching the contact in Suite. This makes it easier for the customers to use Open-ID since they would otherwise need to coordinate and import the identifiers used for the Open-ID providers supported. For this to be acceptable we need to make sure that we’re not persisting the contact-field-value in DP.