# OpenID Connect Provider

## Presentation

OpenID Connect is a protocol based on REST, OAuth 2.0 and JOSE stacks. It is described here: http://openid.net/connect/.

LL::NG can act as an OpenID Connect Provider (OP). It will answer to OpenID Connect requests to give user identity (trough ID Token) and information (trough User Info end point).

As an OP, LL::NG supports a lot of OpenID Connect features:

- Authorization Code, Implicit and Hybrid flows
- Publication of JSON metadata and JWKS data (Discovery)
- `prompt`, `display`, `ui_locales`, `max_age` parameters
- Extra claims definition
- Authentication context Class References (ACR)
- Nonce
- Dynamic registration
- Access Token Hash generation
- ID Token signature (HS256/HS384/HS512/RS256/RS384/RS512)
- UserInfo endpoint, as JSON or as JWT
- Request and Request URI
- Session management
- FrontChannel Logout
- BackChannel Logout
- PKCE (Since `2.0.4`) - See RFC 7636
- Introspection endpoint (Since `2.0.6`) - See RFC 7662
- Offline access (Since `2.0.7`)
- Refresh Tokens (Since `2.0.7`)

## Configuration

### OpenID Connect Service

See OpenID Connect service configuration chapter.

### IssuerDB

Go in `General Parameters` » `Issuer modules` » `OpenID Connect` and configure:

- Activation: set to `On`.
- Path: keep `^/oauth2/` unless you need to use another path
- Use rule: a rule to allow user to use this module, set to `1` to always allow.

For example, to allow only users with a strong authentication level:

    $authenticationLevel > 2

### Configuration of LL::NG in Relying Party

Each Relying Party has its own configuration way. LL::NG publish its OpenID Connect metadata to ease the configuration of client.

The metadata can be found at the standard "Well Known" URL: http://auth.example.com/.well-known/openid-configuration

An example of its content:

    {
       "end_session_endpoint" : "http://auth.example.com/oauth2/logout",
       "jwks_uri" : "http://auth.example.com/oauth2/jwks",
       "token_endpoint_auth_methods_supported" : [
          "client_secret_post",
          "client_secret_basic"
       ],
       "token_endpoint" : "http://auth.example.com/oauth2/token",
       "response_types_supported" : [
          "code",
          "id_token",
          "id_token token",
          "code id_token",
          "code token",
          "code id_token token"
       ],
       "userinfo_signing_alg_values_supported" : [
          "none",
          "HS256",
          "HS384",
          "HS512",
          "RS256",
          "RS384",
          "RS512"
       ],
       "id_token_signing_alg_values_supported" : [
          "none",
          "HS256",
          "HS384",
          "HS512",
          "RS256",
          "RS384",
          "RS512"
       ],
       "userinfo_endpoint" : "http://auth.example.com/oauth2/userinfo",
       "request_uri_parameter_supported" : "true",
       "acr_values_supported" : [
          "loa-4",
          "loa-1",
          "loa-3",
          "loa-5",
          "loa-2"
       ],
       "request_parameter_supported" : "true",
       "subject_types_supported" : [
          "public"
       ],
       "issuer" : "http://auth.example.com/",
       "grant_types_supported" : [
          "authorization_code",
          "implicit",
          "hybrid"
       ],
       "authorization_endpoint" : "http://auth.example.com/oauth2/authorize",
       "check_session_iframe" : "http://auth.example.com/oauth2/checksession",
       "scopes_supported" : [
          "openid",
          "profile",
          "email",
          "address",
          "phone"
       ],
       "require_request_uri_registration" : "false",
       "registration_endpoint" : "http://auth.example.com/oauth2/register"
    }

### Configuration of Relying Party in LL::NG

Go in Manager and click on `OpenID Connect Relying Parties`, then click on `Add OpenID Relying Party`. Give a technical name (no spaces, no special characters), like “sample-rp”;

You can then access to the configuration of this RP.

#### Exported attributes

You can map here the attribute names from the LL::NG session to an OpenID Connect claim.

Claim name | Type | Example of corresponding LDAP attribute
--- | --- | ---
sub | string | uid
name | string | cn
given_name | string | givenName
family_name | string | sn
middle_name | string |
nickname | string |
preferred_username | string | displayName
profile | string | labeledURI
picture | string |
website | string |
email | string | mail
email_verified | boolean |
gender | string |
birthdate | string |
zoneinfo | string |
locale | string | preferredLanguage
phone_number | string | telephoneNumber
phone_number_verified | boolean |
updated_at | string |
formatted | string | registeredAddress
street_address | string | street
locality | string | l
region | string | st
postal_code | string | postalCode
country | string | co

So you can define for example:

- name => cn
- family_name => sn
- email => mail

The specific `sub` attribute is not defined here, but in User attribute parameter (see below).

You can also define extra claims and link them to attributes (see below). Then you just have to define the mapping of this new attributes, for example:

- birthplace => l
- birthcountry => co

#### Options

- Authentication:
  - Client ID: Client ID for this RP
  - Client secret: Client secret for this RP (can be use for symmetric signature)
  - Public client (since version `2.0.4`): set this RP as public client, so authentication is not needed on token endpoint
  - Require PKCE (since version `2.0.4`): a code challenge is required at token endpoint (see RFC7636)
- User attribute: session field that will be used as main identifier (`sub`)
- ID Token signature algorithm: Select one of `none`, `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`
- ID Token expiration: Expiration time of ID Tokens. The default value is one hour.
- Force claims to be returned in ID Token: This options will make user attributes from the requested scope appear as ID Token claims.
- Access token expiration: Expiration time of Access Tokens. The default value is one hour.
- Authorization Code expiration: Expiration time of authorization code, when using the Authorization Code flow. The default value is one minute.
- Use refresh tokens: If this option is set, LemonLDAP::NG will issue a Refresh Token that can be used to obtain new access tokens as long as the user session is still valid.
- Allow offline access: After enabling this feature, an application may request the offline_access scope, and will obtain a Refresh Token that persists even after the user has logged off. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess for details. These offline sessions can be administered through the Session Browser.
- Offline session expiration: This sets the lifetime of the refresh token obtained with the offline_access scope. The default value is one month. This parameter only applies if offline sessions are enabled.
- Redirection addresses: Space separated list of redirect addresses allowed for this RP
- Bypass consent: Enable if you never want to display the scope sharing consent screen (consent will be accepted by default). Bypassing the consent is not compliant with OpenID Connect standard.

#### Extra claims

Associate attributes to extra claims if the RP request them, for example `birth` => `birthplace birthcountry`

#### Macros

You can define here macros that will be only evaluated for this service, and not registered in the session of the user.

#### Display

- Display name: Name of the RP application
- Logo: Logo of the RP application