---
title: "Custom"
description: "Learn to create a custom Authentication Provider class for your Application Server easily, configuring with third-party endpoints. (Gitana 4.0)"
product: "Gitana"
version: "4.0"
url: "/documentation/gitana/4.0/developers/app-server/authentication/providers/custom"
---

# Custom

This page provides some guidance on how to define your own custom Authentication Provider class for use within the Application Server.

Note: If you're looking for information on how to easily integrate a third-party Authentication Provider into the Application Server, we recommend first taking a look at the [Local Provider](/documentation/gitana/4.0/developers/app-server/authentication/providers/local.md) as it can be configured to work with third-party endpoints pretty easily.

## Implementation Class

We recommend extending the AbstractProvider class. The basic skeleton of the class might look like this:

```
var AbstractProvider = require("cloudcms-server/middleware/authentication/providers/abstract");

class CustomProvider extends AbstractProvider {

    constructor(req, config) {
        super(req, config);
    }

    handleAuth(req, res, next) {
        super.handleAuth(req, res, next);
    }

    handleAuthCallback(req, res, next, callback) {
        super.handleAuthCallback(req, res, next, callback);
    }

    userIdentifier(profile) {
        return super.userIdentifier(profile);
    }

    parseProfile(req, profile, callback) {
        super.parseProfile(req, profile, callback);
    }

    load(properties, callback) {
        super.load(properties, callback);
    }
}

module.exports = CustomProvider;
```

In your `app.js` file, you can then register this custom provider like this:

```
server.init(function(app, callback) {
    auth.registerProvider("customProvider", require("./customProvider"));
    callback();
});
```

And you can then register it via config:

```
server.start({
    "auth": {
        ...,
        "providers": {
            "myProvider": {
                "type": "customProvider"
            }
        }            
    }
});
```

## Implementation Details

Here are some notes to aid in your implementation.

### `constructor`

In this section, you will generally want to initialize any configuration options ahead of calling into the super method. The config that was provided in the `server.start()` call for the provider is available in the `config` variable.

For example, you might do this:

```
constructor(req, config) {

    if (!config.loginUrl) {
        config.loginUrl = "/login";
    }
    
    super(req, config);
}
```

The `config` is a member variable and can be accessed from the other methods, allowing everything to be configuration driven. The other methods can simply reference `this.config` to get at configuration settings.

### `handleAuth`

This method is called when the browser is redirected to `/auth/myProvider`. Its job is to somehow get a login screen in front of the user. The most frequent way of doing this is to redirect to a login page somewhere.

If you're using the Facebook provider, as an example, this method redirects you to Facebook to log in. Facebook then receives your username and password and authenticates you. It then redirects the browser back to your app with a code that asserts the user's successful authentication.

For example, you might do this:

```
handleAuth(req, res, next) {
\   res.redirect("https://login.mycompany.com?callback=https://myapp.company.com/auth/myProvider/callback");
}
```

This would redirect to a company-wide login page for sign on (provided that you have one implemented). It also passes some information about where to pass the authentication code on success.

### `handleAuthCallback`

This method gets invoked when the authentication code is passed back after a successful login against the identity provider. Its job is to decipher the authentication code and extract the profile that was sent back.

It should then fire the callback. The callback signature is:

```
callback(null, profile, info);
```

Where `profile` is the profile object and `info` is any optional info that might be of interest downstream. This is generally not needed but can be used if there are cases where you wish to send additional data that isn't part of the user profile.

The user `profile` should, at a minimum, look like something like this:

```
{
    "unique_name": "jsmith",
    "given_name": "Joe",
    "family_name": "Smith",
    "email": "jsmith@company.com"
}
```

Where:

- `unique_name` is the unique username for the user
- `given_name` is the first name of the user
- `family_name` is the last name of the user
- `email` is the unique email of the user

### `userIdentifier`

This method gets called to identify the primary key for a profile. By default, this will extract the `unique_name` field from the profile. You can adjust this if you wish.

For example, you could do something like:

```
userIdentifier(profile) {
    return profile["email"];
}
```

### `parseProfile`

This method takes a trusted profile and extracts any user properties or group information from it. The profile was either acquired via a handshake with the backend authentication provider or it was extracted successfully by the adapter from the incoming request.

It should extract the following:

- `userObject` - a JSON object with the Cloud CMS user properties
- `groupsArray` - an array of group IDs to which the user should be added
- `mandatoryGroupsArray` - an array of group IDs that the user must belong to or the sync should fail

The `callback` should be invoked like this:

```
callback(err, userObject, groupsArray, mandatoryGroupsArray);
```

The `userObject` should effectively look something like this (at a minimum):

```
{
    "name": "jsmith",
    "firstName": "Joe",
    "lastName": "Smith",
    "email": "jsmith@company.com"
}
```

### `load`

This method takes `properties` that were extracted from an adapter and loads the profile for the described user directly from the identity provider.

The incoming `properties` has a `token` property, like this:

```
{
    "token": {identifying token}
}
```

This token should be used to load the identity profile. The profile should then be passed back via the callback.

The callback should be invoked like this:

```
callback (err, profile)
```

### `verify`

This method takes untrusted `properties` that were extracted by the adapter and verifies them against the identity provider. Specifically, it takes the `token` that was received and verifies with the identity provider that the `token` is real and valid and acquires the profile for it.

The incoming `properties` has a `token` property, like this:

```
{
    "token": {identifying token}
}
```

The callback should be invoked like this:

```
callback (err, valid, profile)
```

Where `valid` should be set to false if the token is not valid.
