Tutorial: Custom login

Step by stepAuthentication Custom login

The custom login method makes it possible to use an external trusted and managed system (or custom provider) to authenticate a user within a [[service]] application.

More precisely, the client application authenticates the user with the custom provider, which replies with a signed identity token (which is not a [[service]] authentication token). The client application then request the [[service]] authentication service for exchanging this identity token against a regular [[service]] authentication token.

Configuring a custom provider

First of all, in the [[console]], you must enable the "custom login" method within the "authentication" tab.

Then you can add a new custom provider assigning it a unique name (identifier). When created, it is assigned a secret key by the [[service]] authentication service. You can't read it in the [[console]] UI (as it is secret), but you can copy it to the clipboard using the dedicated button.

You will then have to paste it within the code of your custom provider, so that the generated identity tokens are signed with it.

The [[console]] UI makes it possible to generate a new secret for a given custom provider at anytime. In this case, don't forget to update accordingly the part of the code of your custom provider that signs the generated identity tokens.

Generating an identity token

The identity tokens expected by the [[service]] authentication service are JSON Web Tokens (JWT). They can be easily forged using one of the many available libraries (you can start from Wikipedia for a quick overview).

Identity tokens must be signed with the SHA-256 HMAC algorithm and include the following claims:

Claim Mandatory
Optional
Type Description
iat M Number Date the token was issued, expressed in seconds since the Unix epoch.
exp M Number Date until which the token is valid, expressed in seconds since the Unix epoch. Login will fail with an expired token.
nbf O Number Date from which the token is valid, expressed in seconds since the Unix epoch. If not set, it defaults to iat.
d M Object Identity details about the authenticated end user (see below).

Even if identity tokens can freely include any data, they shall be less than 1024 characters.

The data claim d:

  • must include:
    • the provider attribute that equals the customer provider identifier assigned in the [[console]] (as a String),
    • the providerUid attribute that uniquely identifies the user with the customer provider (as a String).
  • may optionally include:
    • the providerProfile attribute that represents any profile data about the identified user. Any other attributes are ignored by [[service]].

Logging in with an identity token

Use the following snippet to authenticate an end user with an identity token [[snippet]]:

// Authenticate the user with the custom provider
var idToken = getAnIdentityTokenFromMyCustomProvider(myemail, mypassword); 
// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>/");
// Log in with the idToken token
ref.authWithCustomProvider("myCustomProvider", idToken, function(error, auth) {
    if (error) {
      switch (error.code) {
        case "INVALID_TOKEN":
          console.log("Authentication failed, check your credentials!");
          break;
        default:
          console.log("An unexpected error occurs, please retry and contact your administrator.", error);
      }
    } else {
      console.log("Authentication succeeded", auth);
    }
  });
// Authenticate the user with the custom provider
var idToken = getAnIdentityTokenFromMyCustomProvider(myemail, mypassword); 
// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>/");
// Log in with the idToken token
ref.authWithCustomProvider("myCustomProvider", idToken)
   .then(auth => {
      console.log("Authentication succeeded", auth);
   })
   .catch(error => {
      switch (error.code) {
        case "INVALID_TOKEN":
          console.log("Authentication failed, check your credentials!");
          break;
        default:
          console.log("An unexpected error occurs, please retry and contact your administrator.", error);
      }
    });
String idToken = getAnIdentityTokenFromMyCustomProvider(myemail, mypassword);
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
String AUTH_TOKEN = getToken();
ref.authWithCustomProvider("myCustomProvider", idToken, new OnAuth(){
  @Override
  public void onComplete(@Nullable AuthResponse response) {
    // End user authenticated
  }
  @Override
  public void onError(WebcomError error) {
    // End user not authenticated
  }
});
let idToken = getAnIdentityTokenFromMyCustomProvider(id: myemail, secret: mypassword)
let ref = WCWebcom(url: "file://io./base/<your-app>")
let AUTH_TOKEN = getToken()
ref?.auth(withCustomProvider: "myCustomProvider", withIdToken: idToken, onComplete: { (error, authInfo) in
            if (error != nil){
                // End user not authenticated
                print(error.debugDescription)

            }else {
                // End user authenticated
            }
})

The auth parameter received by the authentication callback function is a JSON structure representing the identity used to log in. In addition to the generic fields, it includes the following ones:

Field Type Description
provider String Equals the custom provider identifier assigned in the [[console]].
providerUid String The internal user identifier provided by the custom provider within the identity token.
providerProfile Object The user profile provided by the custom provider within the identity token (if any).
displayName String A human-readable description of the authenticated end user extracted from the previous profile data. It can be missing if no description can be found.

If the identity used to log in is not bound to any [[service]] account, then a new account is automatically created (its id can be retrieved with the uid field) and the identity is bound to it.