Navigation

Custom Authentication

Overview

The Custom authentication provider allows users to authenticate with an authentication system that is independent from Stitch. The external system must return a signed JSON Web Token that contains a unique ID value for the authenticated user. The Custom authentication provider uses this JWT to identify your application’s users.

Stitch imposes no restrictions on the methods and requirements that the system uses to authenticate users. For example, the system could require two factor authentication, specific user metadata, or any other information before it authenticates a user.

Diagram of custom authentication architecture.

Configuration

You can enable the Custom authentication provider from the Stitch UI by selecting Custom Authentication from the Users > Providers page.

You can enable the Custom authentication provider with stitch-cli by importing an application directory that contains a configuration file for the provider.

The configuration file must be named custom-token.json and stored in the /auth_providers directory. Configuration files for the Custom authentication provider have the following form:

/auth_providers/custom-token.json
{
  "name": "custom-token",
  "type": "custom-token",
  "config": {
    "audience": "<JWT Audience>",
    "signingAlgorithm": "<JWT Signing Algorithm>",
  },
  "secret_config": {
    "signingKeys": [
      "<Signing Key Secret Name>",
      ...
    ]
  },
  "metadata_fields": [
    {
      "required": <boolean>,
      "name": "<JWT Field Path>",
      "field_name": "<Metadata Field Name>",
    },
    ...
  ],
  "disabled": <boolean>,
}

The Custom authentication provider has the following configuration options:

Field Description

Signing Algorithm

config.signingAlgorithm

Required. The cryptographic method that the external system uses to sign the JWT. Custom authentication supports JWTs signed using any of the following algorithms:

  • HS256
  • RS256

Signing Key (Secret Name)

secret_config.signingKeys

Required. A list of the names of up to three Secrets that each contain a signing key used by the external authentication system to sign JWTs. Each signing key Secret must be a string with length between 32 and 512 characters.

Warning

A Signing Key is a secret key and anyone with the key can issue valid user credentials for your app. Ensure that it’s never stored in a publicly accessible location, such as a git repository, message board, or in your code.

Audience

config.audience
Optional. The value of the aud field in JWTs returned by the external system. By default, Stitch expects the aud field to contain the App ID of the Stitch app for which the provider is configured.

Metadata Fields

metadata_fields

Optional. Additional data that describes each user. Each metadata field is mapped from a field included in the JWT. Stitch exposes metadata fields in the data object of each user’s user object and refreshes a user’s metadata whenever they log in.

../../_images/custom-auth-metadata-fields.png

To require a metadata field from a custom authentication configuration file, add an entry for the field to the metadata_fields array. Each entry should be a document of the following form:

{
  required: <boolean>,
  name: "<field path>",
  field_name: "<metadata field name>"
}
Field Description

Required

required
Required. If true, the metadata field is required for all custom authentication users, i.e. the JWT returned by the external system must have a value assigned to the field designated by Path.

Path

name
Required. The JWT field that contains the value for the metadata field, specified in dot notation.

Field Name

field_name

Optional. The name of the metadata field that Stitch includes in the custom user object’s data document.

If not specified, Field Name defaults to the same name as the most deeply-nested field listed in Path. For example, given a Path of location.primary.city, Stitch would set the value of Field Name to city.

Note

Field Name may contain no more than 64 characters.

Example

Consider the following JWT returned from an external authentication system that includes additional information about the user in the user_data field:

{
  "aud": "myapp-abcde",
  "exp": 1516239022,
  "sub": "24601",
  "user_data": {
    "name": "Jean Valjean",
    "aliases": [
      "Monsieur Madeleine",
      "Ultime Fauchelevent",
      "Urbain Fabre"
    ]
  }
}

We want to include this user’s data in their user object, so we specify the following metadata fields to map the values:

Path Field Name
user_data.name name
user_data.aliases aliases

We can now access the mapped values directly from the user object, which would resemble the following for the given JWT:

{
  "id": "59fdd02846244cdse5369ebf",
  "type": "normal",
  "data": {
    "name": "Jean Valjean",
    "aliases": [
      "Monsieur Madeleine",
      "Ultime Fauchelevent",
      "Urbain Fabre"
    ]
  },
  identities: [
    {
      "id": "24601",
      "provider_type": "custom-token",
      "data": {
        "name": "Jean Valjean",
        "aliases": [
          "Monsieur Madeleine",
          "Ultime Fauchelevent",
          "Urbain Fabre"
        ]
      },
    }
  ]
}

Usage

Authenticate a User

To log a user in to your app with the Custom authentication provider, call StitchAuth.loginWithCredential() with an instance of CustomCredential created with a signed JWT from the external authentication system.

const jwtString = getTokenFromCustomBuiltAuthSystem();
const credential = new CustomCredential(jwtString);

Stitch.defaultAppClient.auth.loginWithCredential(credential)
  .then(authedUser => console.log(`logged in with custom auth as user ${authedUser.id}`))
  .catch( err => console.error(`failed to log in with custom auth: ${err}`))

To log a user in to your app with the Custom authentication provider, instantiate a CustomCredential instance with a signed JWT from the external authentication system and pass it as the argument to StitchAppClient.loginWithCredential().

String _jwtString = getTokenFromCustomBuiltAuthSystem();
CustomCredential credential = CustomCredential(_jwtString);

Stitch.getDefaultAppClient().getAuth().loginWithCredential(credential)
    .addOnCompleteListener(new OnCompleteListener<StitchUser>() {
        @Override
        public void onComplete(@NonNull final Task<StitchUser> task) {
            if (task.isSuccessful()) {
                Log.d("stitch", "logged in with custom auth as user " + task.getResult().id);
            } else {
                Log.e("stitch", "failed to log in with custom auth:", task.getException());
            }
        }
    });

To log a user in to your app with the Custom authentication provider, instantiate a CustomCredential instance with a signed JWT from the external authentication system and pass it to the StitchAuth.login(withCredential:_:) method as the withCredential argument.

let jwtString = getTokenFromCustomBuiltAuthSystem()
let credential = CustomCredential.init(withToken: jwtString)

Stitch.defaultAppClient!.auth.login(withCredential: credential) { result in
  switch result {
  case .success(let user):
    print("logged in with custom auth as user \(user.id)")
  case .failure(let error):
    print("failed to log in with custom auth: \(error)")
}

JSON Web Tokens

The external authentication system must return a JSON web token that uniquely identifies the authenticated user. JSON web tokens are an industry standard (RFC 7519) for securely representing claims between two parties. A JWT is a string that consists of three parts: a header, a payload and a signature and has the following form:

<header>.<payload>.<signature>

Payload

The payload portion of the JWT consists of a Base64UrlEncoded document of the following form:

{
  "aud": "<stitch app id>"
  "sub": "<unique user id>",
  "exp": <NumericDate>,
  "iat": <NumericDate>,
  "nbf": <NumericDate>,
  ...
}
Field Description
aud
Required. The audience of the token. By default, Stitch expects this value to be the App ID of your Stitch application. If your external authentication service returns a different aud value, you should specify that value instead.
sub
Required. The subject of the token. The value should be a unique ID for the authenticated user from your custom-built authentication system.
exp

Required. The Expiration date of the token. The value should be a NumericDate number indicating the time at which the token expires.

Note

MongoDB Stitch will not accept expired authentication tokens.

iat
Optional. The “issued at” date of the token . The value should be a NumericDate number that indicates the time after which the token is considered valid. This field is functionally identical to nbf.
nbf
Optional. The “not before” date of the token. The value should be a NumericDate number that indicates the time before which the token is considered invalid. This field is functionally identical to iat.

Note

Stitch ignores any additional fields in the JWT payload unless you have mapped them to metadata fields in the provider configuration. Stitch includes the values of mapped fields in the data document of the authenticated user’s user object.

Signature

The signature portion of the JWT is a hash of the encoded token header and payload. To form the signature, concatentate the encoded header and payload with a period and sign the result with the Signing Key specified in the authentication provider configuration using the hashing algorithm specified in the "alg" field of the header.

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  signingKey
)