The Webcom Authentication Service basically maintains an authentication state that identifies the end-user currently signed in to a given Webcom application on a given device (where the Webcom client application is executed).
The Webcom SDK provides with proper APIs to:
- update the authentication state by signing a user in or out,
- track the authentication state updates using authentication callbacks.
Authentication model
The authentication state (AuthState) gathers the following attributes about the currently signed in end-user:
-
AccountUid: unique identifier of the Webcom “account” associated with the end-user. This id is unique across all users of the Webcom application whatever the authentication method used to sign in. This id should be used within the application data to refer to the end-user.
-
Token: Webcom authentication token that encodes the current authentication state. If your application uses a specific backend, this token may be passed along to requests that require user privileges.
-
ExpirationDate: date that the authentication state (and hence the token) is valid until.
-
SignedInIdentity: “identity” used by the end-user to sign in (that is, the data recognized by some identity provider to identify the user). In Webcom model, identities in turn gather the following attributes:
-
Provider: gives the authentication method used to sign the user in. Each identity is associated to a unique and specific authentication method. Each authentication method corresponds to a specific “identity provider”, which can be external to Webcom platform. The complete list of available authentication methods or identity providers is given in the “Signing in and out” chapter.
-
ProviderUid: identifier representing the identity used to sign in. This identifier is unique relatively to the authentication method, that is, unique across all users that are authenticated by a given identity provider. However, the same identifier may refer to distinct users relatively to distinct providers. That's why this identifier is strongly discouraged to identify end-users within an application.
-
CreationDate: date/time when the identity was first associated to the Webcom account of the user. In other words, it is the creation date of the identity from the Webcom viewpoint (and not from the identity provider one).
-
DisplayName: optionally indicates (depending on the identity provider) a friendly display name for the signed-in user.
-
ProviderProfile: gives some optional additional information about the signed-in user, which is provided by the identity provider. This piece of information is completely specific to the authentication method.
-
ExtraProviderData: some optional sensible data, which are also provided by the identity provider. In contrary to the ProviderProfile, these are not stored persistently within the authentication state and are excluded from the Webcom authentication token. They typically include the user Access Token in case of an OAuth2-based authentication method.
-
-
Context: gives the list of other identities used by the end-user to authenticate within this authentication session. In other words, a user may authenticate with several identities. The Webcom Authentication Service actually implements multi-factor authentication using multi-identity authentication. Each authentication factor corresponds to an identity of the user. Each factor contained in the authentication “context” provides in turn the following pieces of information:
- Provider: identity provider associated with the authentication factor,
- ProviderUid: identifier of the user (relatively to the identity provider) associated with the authentication factor,
- SignInDate: date when the user authenticated with this factor. It is useful for example to control that a secondary factor is not too old wrt. the main one.
Thus, when the authentication context is empty, the user is authenticated with a single factor and this “main factor” is described by the Provider and ProviderUid attributes at the first level of the authentication state. When the authentication context contains n factors (n > 0), the user is authenticated with n+1 factors. The most recent factor is the one described by the Provider and ProviderUid attributes at the first level of the authentication sate, the second-to-last one is described by the first element of the Context attribute... and the oldest factor is described by the last element of the context attribute.
The Webcom SDK for JavaScript for JavaScript represents the authentication state using a JSON object with the following properties and correspondence to the authentication state attributes:
JSON property | Mandatory Optional |
Type | Authentication state attribute | |
---|---|---|---|---|
uid |
M | string | AccountUid | |
webcomAuthToken |
M | string | Token | |
expires |
M | number | ExpirationDate | expressed in seconds since Unix Epoch |
provider |
M | string | SignedInIdentity / Provider | |
providerUid |
M | string | SignedInIdentity / ProviderUid | |
createdAt |
M | number | SignedInIdentity / CreationDate | expressed in milliseconds since Unix Epoch |
displayName |
O | string | SignedInIdentity / DisplayName | |
providerProfile |
O | object | SignedInIdentity / ProviderProfile | given as a JSON object specific to the identity provider |
extra |
O | object | SignedInIdentity / ExtraProviderData | given as a JSON object specific to the identity provider |
context |
M | array | Context | |
context[i].provider |
M | string | Context / Provider | |
context[i].providerUid |
M | string | Context / ProviderUid | |
context[i].signedInAt |
M | number | Context / SignInDate | expressed in seconds since Unix Epoch |
Only the displayName
, providerProfile
and extra
properties are optional. The context
property is mandatory but
may be an empty array when the user is signed in with a single factor.
Note that this JSON object (without the
webcomAuthToken
andextra
properties) is also embedded within the Webcom authentication token and is therefore passed to security rules.
Consequently, security rules can accommodate the authentication method or the available additional authentication factors used to sign in, as shown in this complete example.
The Webcom SDK for Android represents the authentication state using the AuthenticationDetails class with the following properties and correspondence to the authentication state attributes:
Attribute | Type | Authentication state attribute |
---|---|---|
uid |
String | AccountUid |
authenticationToken |
String | Token |
expirationDate |
java.util.Date | ExpirationDate |
provider |
AuthenticationFactor.Provider | SignedInIdentity / Provider |
providerUID |
String | SignedInIdentity / ProviderUid |
creationDate |
java.util.Date | SignedInIdentity / CreationDate |
displayName |
String? | SignedInIdentity / DisplayName |
providerProfile |
Map<String,String>? | SignedInIdentity / ProviderProfile |
extra |
ExtraIdentityDetails | SignedInIdentity / ExtraProviderData |
previousFactors |
List<AuthenticationFactor> | Context |
The Webcom SDK for iOS represents the authentication state using the
AuthenticationDetails
struct with the following properties and
correspondence to the authentication state attributes:
AuthenticationDetails property |
Type | Authentication state attribute |
---|---|---|
uid |
String | AccountUid |
authenticationToken |
String | Token |
expirationDate |
Date | ExpirationDate |
provider |
AuthenticationProvider | SignedInIdentity / Provider |
providerUID |
String | SignedInIdentity / ProviderUid |
creationDate |
Date | SignedInIdentity / CreationDate |
displayName |
String? | SignedInIdentity / DisplayName |
providerProfile |
[String: Any] | SignedInIdentity / ProviderProfile |
previousProviderIdentities |
[AuthenticationProviderIdentity] | Context |
Authentication callbacks
The main way to watch the current authentication state maintained by the Webcom Authentication Service is to register authentication callbacks. These functions are called each time the authentication state changes and are passed the authentication state.
If an authentication operation is performed but doesn't change the current authentication state, the callbacks are not called. If an authentication operation fails, then the current authentication state is unchanged (it remains in the previous state) and callbacks are called with the failure error.
Authentication callbacks in JavaScript are passed two parameters:
error
: it is notnull
if the authentication operation that triggers the callback has failed. In this case, it is a JSON object with 2 mandatory properties:code
(the error code, see the Error messages) andmessage
(a non-localized human-readable message).authState
: it must be considered only if theerror
parameter isnull
. If so, it is eithernull
if no user is currently signed in, or the JSON object representing the authenticated user if a user is currently signed in.
Authentication callback functions may be registered or unregistered using the
subscribe()
and
unsubsribe()
methods of the
Authentication Service instance associated with your Webcom
application instance. The following snippet shows a complete example (replace “<your-app>” with your actual application identifier):
// const app = Webcom.App("<your-app>"); // UNCOMMENT if you haven't yet an instance of your app!
// Get an instance of the authentication service
const auth = app.authentication;
// Define an authentication callback
const authCb = (error, authState) => {
if (error) {
switch (error.code) {
case "INVALID_CREDENTIALS":
console.log("The email or password is incorrect.");
break;
case "PROVIDER_DISABLED":
console.log("The email/password method is disabled in the application. It must be enabled in the Webcom developer console.");
break;
default:
console.log("An unexpected error occurs, please retry and contact your administrator.", error);
}
} else {
console.log("Authentication succeeded");
console.log("Authentication state", authState.state); // "none"|"some"|"required"
console.log("Authentication details", authState.details);
}
};
// Register it
auth.subscribe(authCb);
// 'authCb' is called a first time with the current authentication state
// { ...
// Within this fragment, 'authCb' is called each time the authentication state changes
// ... }
// Unregister it
auth.unsubscribe(authCb);
Authentication callbacks in Android are implemented by Kotlin lambdas of type (AuthenticationEvent> -> Unit
.
AuthenticationEvent
event is a
sealed class with the following subtypes:
AuthenticationEvent.Rejected
is an event that reports a failed sign-in operation,AuthenticationState.Authenticated
is an event that reports a successful sign-in operation,AuthenticationState.Unauthenticated
is an event that reports a successful sign-out operation,AuthenticationState.Invalid
is an event that reports an expiration of the previously signed-in user authentication. From now on, all further read and write operations are delayed until a new explicit sign-in or sign-out operation occurs.
They can be registered using the
AuthenticationService.subscribe()
method, and further unregistered using the
cancel()
method on the previously
returned object.
val myApp = WebcomApplication.default // the app defined by the 'webcom.properties' asset file
val authenticator = myApp.authenticationService
val subscription = authenticator.subscribe { // it: AuthenticationEvent
when (it) {
is AuthenticationState.Authenticated ->
print("${it.details.displayName} has logged in")
is AuthenticationState.Unauthenticated ->
print("The user has logged out")
is AuthenticationState.Invalid ->
print("The previous authentication has expired, waiting for logging in or out")
is AuthenticationEvent.Rejected ->
print("An authentication attempt has failed: ${it.data.error.errorCode}")
}
}
// ...and then later...
subscription.cancel()
In Swift, authentication callbacks are functions receiving an AuthenticationEvent
parameter.
This type is an enum
with two cases:
.change
indicates that the authentication state changed. This case has anAuthenticationState
associated value..failure
indicates that an authentication process failed. This case has aWebcomError
associated value giving the cause of this failure.
The AuthenticationState
enum
has three cases:
.authenticated
indicates that an end user has signed in. This case has anAuthenticationDetails
associated value..invalid
indicates that the end user authentication has expired, or it could not be restored when changing from offline to online. This case does not have an associated value..unauthenticated
indicates that the end user has signed out. This case does not have an associated value.
Registering (resp. unregistering) an authentication callback consists in subscribing to (resp. unsubscribing from) an event corresponding to the change of the authentication state.
Subscribing is done with the subscribe()
method of an AuthenticationService
object.
Unsubscribing is done with the cancel()
method of the AuthenticationSubscription
object returned by the subscription.
The following snippet shows an example:
let authenticationService = Webcom.defaultApplication.authenticationService // application is configured in the `Info.plist` file
authenticationService.subscribe { event in
// This code is called each time the authentication state changes.
switch event {
case let .change(state: .authenticated(details: details)):
print("successfully authenticated as:", details.uid)
case .change(state: .invalid):
print("authentication expired")
case .change(state: .unauthenticated):
print("logout succeeded")
case let .failure(reason: error):
print("authentication failed:", error)
}
}
Limitations
-
The authentication state is purely local to the client device where the Authentication Service is executed, there is no central state (or session) maintained at the Webcom application level by the back end.
For example, if the same user is signed in to your app both on a mobile phone and on a desktop web interface, then signing out from the mobile phone doesn't sign s/he out from the web interface. -
Only one end-user can sign in at a time to a given Webcom application instance on the same device.
For example, if Mary signs in first to app A on a tablet, and then Peter signs in to the same instance of app A on the same tablet (within the same user session from the tablet OS viewpoint), then Mary is eventually signed out from app A and Paul signed in to app A. -
However, the same end-user can sign in to various application instances at a time on the same device.
For example, Mary can sign in to both apps A and B on her tablet, or to two different instances of app A on her tablet. -
The authentication state of a given user for a given Webcom application instance on a given device is valid until:
- either the user signs out from this application on this device,
- or the corresponding authentication token expires.