### Navigation

- index
- modules |
- next |
- previous |
- Gate One Documentation »
- Developer Documentation »
- Embedding Gate One Into Other Applications »

# API Authentication

Gate One includes an authentication API that can be used when embedded into other applications. It allows the application embedding Gate One to pre-authenticate users so they won't have to re-authenticate when their browser connects to the Gate One server. Here's how it works:

## Enable API Authentication

Set `auth = "api"` in your server.conf:

    # grep "^auth" server.conf
    auth = "api"

## Generate an API Key/Secret

    # ./gateone.py --new_api_key
    [I 120905 14:00:07 gateone:2679] A new API key has been generated: NDEzMWEwYTdlZTAzNDkxMWIwMDI4YzJmZTk4YzI4OWJjM
    [I 120905 14:00:07 gateone:2680] This key can now be used to embed Gate One into other applications.

Note

The secret is not output to the terminal to avoid it being captured in session logs.

API keys and secrets are stored in your 30api_keys.conf like so:

    {
        "*": {
            "gateone": {
                "api_keys": {
                    "<API Key>": "<Secret>",
                    "<API Key 2>": "<Secret 2>"
                }
            }
        }
    }

You'll need to have a look at your 30api_keys.conf to see what the 'secret' is:

    # cat settings/30api_keys.conf
    {
        "*": {
            "gateone": {
                "api_keys": {
                    "NDEzMWEwYTdlZTAzNDkxMWIwMDI4YzJmZTk4YzI4OWJjM": "M2U5YTMxMGQ3OWNlNDJlMTg5NmY0NmUyOTk5MWYwYWFiN"
                }
            }
        }
    }

In the above example our API key would be, `"NDEzMWEwYTdlZTAzNDkxMWIwMDI4YzJmZTk4YzI4OWJjM"` and our API secret would be, `"M2U5YTMxMGQ3OWNlNDJlMTg5NmY0NmUyOTk5MWYwYWFiN"`.

Tip

You can set the API Key and secret to whatever you like by editing your 30api_keys.conf. By default they're random, 45-character strings but they can be any combination of characters other than colons and commas--even Unicode!. The following is a perfectly valid API key and secret:

`"ʕ•ᴥ•ʔ ／人 ◕ ‿‿ ◕ 人＼": "↑ ↑ ↓ ↓ ← → ← → Ⓑ Ⓐ ♥‿♥"`

## Generate An Auth Object

The next step is to generate a JSON object (auth) from your application and pass it to `GateOne.init()`. The 'auth' object must contain the following information:

> api_key
>   The key that was generated when you ran `./gateone.py --new_api_key`
> upn
>   The username or userPrincipalName (aka UPN) of the user you wish to preauthenticate.
> timestamp
>   A JavaScript-style timestamp: 13 digits representing the amount of milliseconds since the epoch (January 1, 1970)
> signature
>   A valid HMAC signature that is generated from the api_key, upn, and timestamp (in that order).
> signature_method
>   The HMAC signature method that was used to sign the authentication object. Currently, only HMAC-SHA1 is supported.
> api_version
>   The version of Gate One's API authentication to use. Currently, only '1.0' is valid.

Here's an example 'auth' object:

    authobj = {
        'api_key': 'MjkwYzc3MDI2MjhhNGZkNDg1MjJkODgyYjBmN2MyMTM4M',
        'upn': 'joe@company.com',
        'timestamp': '1323391717238',
        'signature': "f6c6c82281f8d56797599aeee01a5e3efab05a63",
        'signature_method': 'HMAC-SHA1',
        'api_version': '1.0'
    }

This object would then be passed to `GateOne.init()` like so:

    GateOne.init({auth: authobj})

Assuming the signature is valid Gate One would then inherently trust that the user connecting over the WebSocket is joe@company.com.

Note

Authentication objects (aka "authentication tokens") are only valid within the time frame specified in the --api_timestamp_window setting. They also can't be used more than once (to negate replay attacks).

# Example API Authentication Code

The following are examples demonstrating how to generate valid 'auth' objects in various programming languages.

## Python

    import time, hmac, hashlib, json
    secret = "secret"
    authobj = {
        'api_key': "MjkwYzc3MDI2MjhhNGZkNDg1MjJkODgyYjBmN2MyMTM4M",
        'upn': "joe@company.com",
        'timestamp': str(int(time.time() * 1000)),
        'signature_method': 'HMAC-SHA1',
        'api_version': '1.0'
    }
    hash = hmac.new(secret, digestmod=hashlib.sha1)
    hash.update(authobj['api_key'] + authobj['upn'] + authobj['timestamp'])
    authobj['signature'] = hash.hexdigest()
    valid_json_auth_object = json.dumps(authobj)

Here's a create_signature() function that can be used as a shortcut to those hash calls above:

    def create_signature(secret, *parts):
        import hmac, hashlib
        hash = hmac.new(secret, digestmod=hashlib.sha1)
        for part in parts:
            hash.update(str(part))
        return hash.hexdigest()

...which could be used like so:

    >>> create_signature(secret, api_key, upn, timestamp)
    'f6c6c82281f8d56797599aeee01a5e3efab05a63'

## PHP

    $secret = 'secret';
    $authobj = array(
        'api_key' => 'MjkwYzc3MDI2MjhhNGZkNDg1MjJkODgyYjBmN2MyMTM4M',
        'upn' => $_SERVER['REMOTE_USER'],
        'timestamp' => time() * 1000,
        'signature_method' => 'HMAC-SHA1',
        'api_version' => '1.0'
    );
    $authobj['signature'] = hash_hmac('sha1', $authobj['api_key'] . $authobj['upn'] . $authobj['timestamp'], $secret);
    $valid_json_auth_object = json_encode($authobj);

## Ruby

    require 'cgi'
    require 'openssl'
    require 'json'
    secret = 'secret'
    authobj = {
        'api_key' => 'MjkwYzc3MDI2MjhhNGZkNDg1MjJkODgyYjBmN2MyMTM4M',
        'upn' => 'joe@company.com',
        'timestamp' => (Time.now.getutc.to_i * 1000).inspect,
        'signature_method' => 'HMAC-SHA1',
        'api_version' => '1.0'
    }
    authobj['signature' = OpenSSL::HMAC.hexdigest('sha1', secret, authobj['api_key'] + authobj['upn'] + authobj['timestamp'])
    valid_json_auth_object = JSON.generate(authobj)

### Navigation

- index
- modules |
- next |
- previous |
- Gate One Documentation »
- Developer Documentation »
- Embedding Gate One Into Other Applications »