Glewlwyd OAuth2 Plugin documentation

Single Sign On server, OAuth2, Openid Connect, multiple factor authentication with, HOTP/TOTP, FIDO2, TLS Certificates, etc. extensible via plugins


Glewlwyd OAuth2 Plugin documentation

License: CC BY 4.0

This plugin is based on the OAuth 2 RFC document and allows Glewlwyd to act as an OAuth2 Provider.

Note

This plugin will be deprecated sooner or later. Until then, bugs will still be fixed but no new functionalities will be added.

It’s recommened to use the OIDC plugin instead.

Functionalities summary

The following OAuth2 functionalities are supported:

Access token format

Glewlwyd OAuth2 plugin uses JWTs as access tokens. Therefore, the access token can be used by the client or the third party web service to identify the user and the scopes available with this access token.

An access token payload has the following JSON format:

{
  username: "user1",        // Username that was provided this access_token
  salt: "abcdxyz1234",      // Random string to avoid collisions
  type: "access_token",     // Hardcoded
  iat: 1466556840,          // Issued at time in Epoch Unix format
  expires_in: 3600,         // Number of seconds of validity for this token
  scope: "scope1 g_profile" // scopes granted to this access token in a string separated by spaces
}

Generate a key pair for JWT access tokens signatures

To create a key/certificate pair in RSA or ECDSA format, run the following commands on a linux shell with openssl installed:

$ # RSA KEY
$ # private key
$ openssl genrsa -out private-rsa.key 4096
$ # public key
$ openssl rsa -in private-rsa.key -outform PEM -pubout -out public-rsa.pem

$ # ECDSA KEY
$ # private key
$ openssl ecparam -genkey -name secp521r1 -noout -out private-ecdsa.key
$ # public key
$ openssl ec -in private-ecdsa.key -pubout -out public-ecdsa.pem

For more information on keys generation, see OpenSSL Documentation.

Installation

plugin-oauth2

In the administration page, go to Parameters/Plugins and add a new plugin by clicking on the + button. In the modal, enter a name and a display name (the name must be unique among all user backend instances). Select the type Glewlwyd OAuth2 plugin in the Type drop-down button.

Below is the definition of all parameters.

Name

Name (identifier) of the plugin instance, must be unique among all the plugin instances, even of a different type.

Display name

Name of the instance displayed to the user.

JWT Type

Algorithm used to sign access tokens and ID Tokens.

The algorithm supported are RSA and ECDSA using a private and a public key, and SHA using a shared secret.

Key size

Size of the key to sign the tokens. The sizes supported are 256 bits, 384 bits or 512 bits.

Secret key

Private key file used to sign if the selected algorithm is RSA or ECDSA. Must be a PEM format file. Shared secret if the selected algorithm is SHA.

Public key

Public key file used to validate access tokens if the selected algorithm is RSA or ECDSA. Must be a PEM format file.

Access token duration (seconds)

Duration of each access tokens. Default value is 3600 (1 hour).

Refresh token duration (seconds)

Duration of validity of each refresh tokens. Default value is 1209600 (14 days).

Code duration (seconds)

Duration of validity of each code sent to the client before requesting a refresh token. Default value is 600 (10 minutes).

Refresh token rolling

If this option is checked, every time an access token is requested using a refresh token, the refresh token issued at time will be reset to the current time. This option allows infinite validity for the refresh tokens if it’s not manually disabled, but if a refresh token isn’t used for more of the value Refresh token duration, it will be disabled.

Authentication type code enabled

Enable response type code.

Revoke all tokens if a client tries to replay a code

If this option is set, when a code is replayed to gain a refresh token, all the refresh and access tokens delivered for this code will be revoked. This option can be used to mitigate replay attacks and enforce tokens security.

Authentication type implicit enabled

Enable response type token.

Authentication type password enabled

Enable response type password.

Authentication type client enabled

Enable response type client_credential.

Authentication type refresh enabled

Enable response type refresh_token.

Specific scope parameters

This section allows to put specific settings for an scope that will override the plugin settings.

The settings that you can override are Refresh token duration and/or Rolling refresh.

Please note that a specific scope parameter has a higher priority than the plugin settings, and if have multiple scopes in a request that have specific settings, the settings will follow the following algorithm:

  • Refresh token duration: The duration provided will be the lowest duration among all the specific scope parameters.
  • Rolling refresh: The value Nohas higher priority, therefore rolling refresh provided will be No if one scope has the value No, Yes otherwise

Additional token values

This section allows to add specific values to the access_tokens that will be taken from the user property values.

You can add as many additional values as you want. If the property isn’t present in the user data, it will be ignored. If the value is multiplier, all values will be present, separated by a comma ,.

PCS - Code challenge (RFC 7636)

This section is used to configure Proof Key for Code Exchange by OAuth Public Clients.

PUCE allowed

Enable this feature if you want to support code challenge.

Method plain allowed

Enable this feature if you want to allow method plain in the code challenge feature. It is not recommended to enable this feature unless you know what you do because this feature is slightly less secure than default method S256.

According to the specifications:

Clients are
permitted to use "plain" only if they cannot support "S256" for some
technical reason and know via out-of-band configuration that the
server supports "plain".

Tokens Introspection (RFC 7662) and Revocation (RFC 7009)

IMPORTANT NOTICE!

Glewlwyd access tokens are JWTs, the original way for resource services to check if an access token is valid and reliable is to check its signature and its expiration date. Token introspection and revocation have been introduced in Glewlwyd, but if the resource service doesn’t use the introspection endpoint, it will miss an inactive token and still consider it valid.

The endpoints /profile, /introspect and /revoke when they are given an access token to authenticate will check if the token is revoked or not.

Allow tokens introspection and invocation

Enable this feature if you want your oauth2 instance to enable endpoints /introspect and /revoke.

Allow for the token client

Enable this feature if your want to allow clients to use endpoints /introspect and /revoke using their client_id and secret as HTTP Basic Auth. The clients will be allowed to introspect and revoke only the tokens that were issued for them.

Required scopes in the access token

Add on or more scopes if you want to allow to use endpoints /introspect and /revoke using valid access tokens to authenticate the requests. The access tokens must have the scopes required in their payload to be valid.

Client secret vs password

When you add or edit a client in Glewlwyd, you can set a client secret or a password. Both can be used to authenticate confidential clients.

The primary difference is that a client secret is a string stored ‘as is’ in the backend (database or LDAP), without hashing, where a client password is stored in a hashed form in the backend, so makes it more difficult for attackers to retrieve it.

A client secret has priority over a client password, which means that if a client has set both client secret and client password, the authentication will be executed with client secret only.

Glewlwyd OAuth 2 endpoints specifications

This document is intended to describe Glewlwyd OAuth 2 plugin implementation.

OAuth endpoints are used to authenticate the user, and to send tokens or other authentication and identification data. The complete specification is available in the OAuth 2 RFC document. If you see an issue or have a question on Glewlwyd OAuth 2 plugin implementation, you can open an issue or send an email to the following address mail@babelouest.org.

Endpoints authentication

Authentication has different faces, and differs with the authorization scheme.

Prefix

All URIs are based on the prefix you will setup. In this document, all API endpoints will assume they use the prefix /api/glwd, and all static file endpoints will assume they use the prefix /.

Login and grant URIs

In this document, the login URI will be displayed as http://login.html, this will be replaced by the values from your environment that you can define in the config file.

OAuth 2 endpoints

Authorization endpoint

This is a multi-method, multi-parameters, versatile endpoint, used to provide authentication management. It handles the following authorization schemes as describe in the OAuth 2 RFC document:

  • Authorization Code Grant (Authorization part)
  • Implicit Grant
URL

/api/glwd/auth

Method

GET POST

Token endpoint

This endpoint is used to provide tokens to the user. It handles the following authorization schemes as describe in the OAuth 2 RFC document:

  • Authorization Code Grant (Access Token part)
  • Resource Owner Password Credentials Grant
  • Client Credentials Grant
  • Refreshing a token
  • Deleting a token
URL

/api/glwd/token

Method

POST

OAuth 2 schemes

Each scheme is described in the following chapter. The description may not be as complete as the OAuth 2 RFC document, consider the RFC as the authority standard.

Authorization code grant - Authorization request

URL

/api/glwd/auth

Method

GET POST

URL (GET) or body (POST) Parameters

Required

`response_type`: text, must be set to `code`
`client_id`: text, client_id that sends the request on behalf of the resource owner, must be a valid client_id
`redirect_uri`: text, redirect_uri to send the resource owner to after the connection, must be a valid redirect_uri for the specified client_id
`scope`: text, scope list that the resource owner will grant access to the client, multiple scope values must be separated by a space

Optional

state: text, an identifier used to prevent requests collisions and bypass, will be sent back as is to the client

Result
Resource owner not authenticated

Code 302

Resource owner is not authenticated with a valid session token.

Redirect to http://login.html?client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&additional_parameters for authentication.

See login paragraph for details.

Scope not granted to the client

Code 302

Redirect to http://login.html?client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&additional_parameters for grant access.

Success response

Code 302

Redirect to redirect_uri?code=code&state=state

with redirect_uri specified in the request, a code generated for the access, and the state specified in the request if any.

Error Scope

Scope is not allowed for this user

Code 302

Redirect to redirect_uri?error=invalid_scope&state=state

with redirect_uri specified in the request, invalid_scope as error value, and the state specified in the request if any.

Error client

Client is invalid, redirect_uri is invalid for this client, or client is not allowed to use this scheme

Code 302

Redirect to redirect_uri?error=unauthorized_client&state=state

with redirect_uri specified in the request, unauthorized_client as error value, and the state specified in the request if any.

Authorization code grant - Authorization Response

URL

/api/glwd/token

Method

POST

Security

If client_id refers to a confidential client, then client_id and client_password must be sent via Basic HTTP Auth.

Data Parameters

Request body parameters must be encoded using the application/x-www-form-urlencoded format.

grant_type: text, must be set to "authorization_code".
code: text, required
redirect_uri: text, must be same redirect_uri used in the authorization request that sent back this code
client_id: text, must be the same client_id used in the authorization request that sent back this code
Success response

Code 200

Content

{
  "access_token":text, jwt token
  "token_type":text, value is "bearer",
  "expires_in":number, set by server configuration
  "refresh_token":text, jwt token
}
Error Response

Code 400

Error input parameters

The combination code/redirect_uri/client_id is incorrect.

Implicit Grant

URL

/api/glwd/auth

Method

GET

URL Parameters

Required

`response_type`: text, must be set to `token`
`client_id`: text, client_id that sends the request on behalf of the resource owner, must be a valid client_id
`redirect_uri`: text, redirect_uri to send the resource owner to after the connection, must be a valid redirect_uri for the specified client_id
`scope`: text, scope list that the resource owner will grant access to the client, multiple scope values must be separated by a space

Optional

state: text, an identifier used to prevent requests collisions and bypass, will be sent back as is to the client

Result
Resource owner not authenticated

Code 302

Resource owner is not authenticated with a valid session token.

Redirect to http://login.html?client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&additional_parameters for authentication.

See login paragraph for details.

Scope not granted to the client

Code 302

Redirect to http://grant.html?client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&additional_parameters for grant access.

See grant paragraph for details.

Success response

Code 302

Redirect to redirect_uri#token=token&state=state

with redirect_uri specified in the request, a code generated for the access, and the state specified in the request if any.

Error Scope

Scope is not allowed for this user

Code 302

Redirect to redirect_uri#error=invalid_scope&state=state

with redirect_uri specified in the request, invalid_scope as error value, and the state specified in the request if any.

Error client

Client is invalid, redirect_uri is invalid for this client, or client is not allowed to use this scheme

Code 302

Redirect to redirect_uri#error=unauthorized_client&state=state

with redirect_uri specified in the request, unauthorized_client as error value, and the state specified in the request if any.

Resource Owner Password Credentials Grant

URL

/api/glwd/token

Method

POST

Data Parameters

Request body parameters must be encoded using the application/x-www-form-urlencoded format.

grant_type: text, must be set to "password".
username: text
password: text
scope: text
Success response

Code 200

Content

{
  "access_token":text, jwt token
  "token_type":text, value is "bearer",
  "expires_in":number, set by server configuration
  "refresh_token":text, jwt token
}
Error Response

Code 403

username or password invalid.

Client Credentials Grant

URL

/api/glwd/token

Method

POST

Security

HTTP Basic authentication with client_id/client_password credentials. Client_id must be set as confidential

URL Parameters

Required

Optional

Data Parameters

Request body parameters must be encoded using the application/x-www-form-urlencoded format.

grant_type: text, must be set to "client_credentials".
scope: text
Success response

Code 200

Content

{
  "access_token":text, jwt token
  "token_type":text, value is "bearer",
  "expires_in":number, set by server configuration
}
Error Response

Code 403

Access denied

Refresh token

Send a new access_token based on a valid refresh_token

URL

/api/glwd/token

Method

POST

Data Parameters

Request body parameters must be encoded using the application/x-www-form-urlencoded format.

grant_type: text, must be set to "refresh_token".
refresh_token: text, a valid ref refresh_token, mandatory
scope: text, must the same scope or a sub scope of the scope used to provide the refresh_token, optional
Success response

Code 200

Content

{
  "access_token":text, jwt token
  "token_type":text, value is "bearer",
  "expires_in":number, set by server configuration
}
Error Response

Code 400

Error input parameters

Invalidate refresh token

Mark a refresh_token as invalid, to prevent further access_token to be generated

URL

/api/glwd/token

Method

POST

Data Parameters

Request body parameters must be encoded using the application/x-www-form-urlencoded format.

grant_type: text, must be set to "delete_token".
refresh_token: text, a valid refresh_token, mandatory
Success response

Code 200

Error Response

Code 400

Error input parameters

Manage refresh tokens endpoints

The following endpoints require a valid session cookie to identify the user. If the user has the scope g_admin, it’s possible to impersonate a user with the optional query parameter ?username={username}.

List refresh tokens

URL

/api/glwd/profile/token

Method

GET

URL Parameters

Optional

`offset`: number, the offset to start the list, default 0
`limit`: number, the number of elements to return, default 100
`pattern`: text, a pattern to filter results, pattern will filter the properties `user_agent` or `issued_for`
`sort`: text, the column to order the results, values available are `authorization_type`, `client_id`, `issued_at`, `last_seen`, `expires_at`, `issued_for`, `user_agent`, `enabled` and `rolling_expiration`
`desc`: no value, is set, the column specified in the `sort` parameter will be orderd by descending order, otherwise ascending
Result
Success response

Code 200

Content

[{
  "token_hash": text, refresh token hash signature
  "authorization_type": text, authorization type used to generate this refresh token, value can be "code" or "password"
  "client_id": text, client_id this refresh token was sent to
  "issued_at": number, date when this refresh token was issued, epoch time format
  "expires_at": number, date when this refresh token will expire, epoch time format
  "last_seen": number, last date when this refresh token was used to generate an access token, epoch time format
  "rolling_expiration": boolean, wether this refresh token is a rolling token, i.e. its expiration date will be postponed on each use to generate a new access token
  "issued_for": text, IP address of the device which requested this refresh token
  "user_agent": text, user-agent of the device which requested this refresh token
  "enabled": boolean, set to true if this refresh token is enabled, i.e. can be used to generate new access tokens, or not
}]
Error Response

Code 403

Access denied

Disable a refresh token by its signature

URL

/api/glwd/profile/token/{token_hash}

Method

DELETE

URL Parameters

Required

`token_hash`: text, hash value of the refresh token to disable, must be url-encoded
Result
Success response

Code 200

Error Response

Code 403

Access denied

Code 404

Refresh token hash not found for this user

Token introspection and revocation

The endpoints POST /introspect and POST /revoke are implementations of the corresponding RFCs Token introspection and revocation and OAuth 2.0 Token Revocation.

Both of them rely on 2 distinct ways to authenticate:

  • HTTP Basic Auth corresponding to the client credentials whose client the token was submitted
  • Authorized Access Token that includes the required scopes for those endpoints

Both authentication methods are non exclusive and the administrator may enable or disable each of them.

Token introspection

URL

/api/glwd/introspect

Method

POST

Data Parameters

Request body parameters must be encoded using the application/x-www-form-urlencoded format.

token: text, the token to introspect, required
token_type_hint: text, optional, values available are 'access_token' or 'refresh_token'
Result
Success response

Code 200

Content

Active token

{
  "username": text, username the token was issued for, if any
  "client_id": text, client the token was issued for, if any
  "iat": number, epoch time when the token was issued
  "nbf": number, epoch time when the token was issued
  "exp": number, epoch time when the token will be (or is supposed to be) expired
  "scope": text, scope list this token was emitted with, separated with spaces
  "token_type": text, type of the token, values may be 'access_token' or 'refresh_token'
}
Error Response

Code 401

Access denied

Code 400

Invalid parameters

Token revocation

URL

/api/glwd/revoke

Method

POST

Data Parameters

Request body parameters must be encoded using the application/x-www-form-urlencoded format.

token: text, the token to introspect, required
token_type_hint: text, optional, values available are 'access_token' or 'refresh_token'
Result
Success response

Code 200

Error Response

Code 401

Access denied

Code 400

Invalid parameters