Official Plugins (Kuzzle v2.x)
openid v1.x
2

About #

Kuzzle Auth OpenID Plugin #

This is the official Kuzzle OpenID authentication plugin.

This plugins allows you to configure multiple strategies to allow users to authenticate themselves from your authentication server using the OpenID protocol.

Kuzzle #

Kuzzle is an open-source backend that includes a scalable server, a multiprotocol API, an administration console and a set of plugins that provide advanced functionalities like real-time pub/sub, blazing fast search and geofencing.

Compatibility matrix #

Kuzzle Version Plugin Version
>= 2.17.3 1.x.x

Installation #

To install this plugin on your Kuzzle stack (for each of your Kuzzle nodes), you will first need a Kuzzle Application like so. (see Getting Started)

Once you have it, you will need to:

  • Import the OpenID plugin,
  • Create a new instance of the plugin
  • And then use it in your application.

You will end up with something like this:

Copied to clipboard!
import { Backend, JSONObject } from 'kuzzle';
import { PluginAuthOpenID } from '@kuzzleio/kuzzle-plugin-auth-openid'; // Import the openid auth plugin

const app = new Backend('kuzzle');

// Implement custom authentication strategy using the OpenID protocol
class PluginAuthGoogle extends PluginAuthOpenID {
  constructor () {
    super('google'); // Create a new strategy named "google"
  }

  // Required method that should return which profiles to give to the user
  async extractor (claims: JSONObject): Promise<ExtractedUserInfo> {
    return {
      profiles: ['kuzzleprofile-default'] // Give the user the profile named "default"
      userdata: {} // Add / Update any informations in the user custom data
    };
  }
}

app.plugin.use(new PluginAuthGoogle()); // Add the plugin to your application

app.start()
  .then(() => {
    app.log.info('Application started');
  })
  .catch(console.error);

Configure a Strategy #

You can find sample configuration files for this plugin in the example folder.

Example

Copied to clipboard!
{
  "plugins": {
    "auth-google": {
      "issuerAutoDiscover": true, // Auto discover issuer endpoint metadata
      "issuerConfig": { // See https://github.com/panva/node-openid-client/blob/main/docs/README.md#issuer
        "issuer": "http://localhost:8080/realms/myrealm"
      },
      "clientConfig": { // https://github.com/panva/node-openid-client/blob/main/docs/README.md#class-client
        "client_id": "myclient",
        // The url has the following format: http://<kuzzle host>/_login/<strategy>
        "redirect_uris": ["http://localhost:7512/_login/keycloak"],
        "response_type": "code",
        "token_endpoint_auth_method": "none"
      },
      /**
       * Interval in milliseconds (default: 1min).
       * Interval at which the plugin will fetch the Json Web Key Certificates from the provider.
       * Thoses certificates are used to verify the provided Access Token and ID Token when
       * a user attempt to login by providing the token directly in the request body.
       */
      "certRefreshInterval": 60000
    }
  }
}

You can try your strategy by visiting http://<kuzzle host>/_login/<strategy name>

Strategy Config Properties #

issuerAutoDiscover #

Auto discover issuer endpoint metadata. When true you only need to specify the issuer in the issuerConfig

The client will try to retrieve metadata information from the endpoint using the .well-known endpoint if there is one.

For more informations see Issuer.discover.

issuerConfig #

Issuer metadata information, for a list properties see Issuer Metadata.

clientConfig #

Client metadata information, for a list properties see Client Metadata.

User Profile Attribution #

Once a user connects to Kuzzle using one of the provided strategies, the user will be granted with each profiles returned by the ProfileExtractor that is starting with kuzzleprofile-. Each entry not starting with kuzzleprofile- will be ignored.

Returned profiles starting with kuzzleprofile- should always match Kuzzle profiles. As an example if you have a profile named visitor, the ProfileExtractor should return a list of profiles containing kuzzleprofile-visitor.

Create custom OpenID Strategy #

Copied to clipboard!
import { Backend, JSONObject } from 'kuzzle';
import { PluginAuthOpenID } from '@kuzzleio/kuzzle-plugin-auth-openid';

const app = new Backend('kuzzle-plugin-openid');

// Implement custom authentication strategy using the OpenID protocol
class PluginAuthGoogle extends PluginAuthOpenID {
  constructor () {
    super('google'); // Create a new strategy named "google"
  }

  // Required method that should return which profiles to give to the user
  async extractor (claims: JSONObject): Promise<ExtractedUserInfo> {
    return {
      profiles: ['kuzzleprofile-default'] // Give the user the profile named "default"
      userdata: {} // Add / Update any informations in the user custom data
    };
  }
}

app.plugin.use(new PluginAuthGoogle());

app.start().then(() => {
  console.log('Application started');
});

Login using your OpenID strategy #

Login using the authentication server interface #

You can send a request to <kuzzle host>:<port>/_login/<strategy>, Kuzzle will then redirect you to the authentication page of the authentication server, once logged in the authentication server will redirect you to the page you configured and you will be given parameters in the query string, to finish the login you need to send thoses parameters to <kuzzle host>:<port>/_login/<strategy>?<received query params> this way Kuzzle can validate the connection and send you a Kuzzle JWT.

Login using an Access Token issued by the authentication server #

If you give a valid access_token inside the body of auth:login to the proper strategy and that access_token has been issued by the same provider and client_id as configured for the given strategy, then Kuzzle will send you a Kuzzle JWT.

example

Copied to clipboard!
await sdk.auth.login('my-openid-strategy', {
  access_token: '<access_token>', // Only the access_token is required
  id_token: '<access_token>' // Not required, but can be provided if you do not want to put user informations inside the access_token
});

Community #