-
Notifications
You must be signed in to change notification settings - Fork 129
Configuration
Make sure you've configured Doorkeeper before continuing.
Verify your settings in config/initializers/doorkeeper.rb:
-
resource_owner_authenticator-
This callback needs to returns a falsey value if the current user can't be determined:
resource_owner_authenticator do if current_user current_user else redirect_to(new_user_session_url) nil end end
-
-
grant_flows-
If you want to use
id_tokenorid_token tokenresponse types you need to addimplicit_oidctogrant_flows:grant_flows %w(authorization_code implicit_oidc)
-
The following settings are required in config/initializers/doorkeeper_openid_connect.rb:
-
issuer-
Identifier for the issuer of the response (i.e. your application URL). The value is a case sensitive URL using the
httpsscheme that contains scheme, host, and optionally, port number and path components and no query or fragment components. -
You can either pass a string value, or a block to generate the issuer dynamically. The block receives
resource_owner,application, andrequestso that the same configuration can serve both ID token issuance (whereresource_ownerandapplicationare available) and the discovery endpoint (where onlyrequestis available):# config/initializers/doorkeeper_openid_connect.rb Doorkeeper::OpenidConnect.configure do # ... issuer do |resource_owner, application, request| request&.base_url || "https://default.example.com" end end
-
For backward compatibility, blocks with arity 0, 1, or 2 are also accepted. An arity-1 block receives
requestfrom the discovery endpoint andresource_ownerfrom the ID token context, while an arity-2 block always receivesresource_ownerandapplication.
-
-
subject-
Identifier for the resource owner (i.e. the authenticated user). A locally unique and never reassigned identifier within the issuer for the end-user, which is intended to be consumed by the client. The value is a case-sensitive string and must not exceed 255 ASCII characters in length.
-
The database ID of the user is an acceptable choice if you don't mind leaking that information.
-
If you want to provide a different subject identifier to each client, use pairwise subject identifier with configurations like below.
# config/initializers/doorkeeper_openid_connect.rb Doorkeeper::OpenidConnect.configure do # ... subject_types_supported [:pairwise] subject do |resource_owner, application| Digest::SHA256.hexdigest("#{resource_owner.id}#{URI.parse(application.redirect_uri).host}#{'your_secret_salt'}") end # ... end
-
-
signing_key- Private key to be used for JSON Web Signature.
- You can generate a private key with the
opensslcommand, see e.g. Generate an RSA keypair using OpenSSL. - You should not commit the key to your repository, but use an external file (in combination with
File.read) and/or the dotenv-rails gem (in combination withENV[...]).
-
signing_algorithm- The signing algorithm used for the ID token, which defaults to
:rs256. The list of supported algorithms can be found here
- The signing algorithm used for the ID token, which defaults to
-
resource_owner_from_access_token- Defines how to translate the Doorkeeper access token to a resource owner model.
Note
Both signing_key and signing_algorithm also accept callable objects (e.g. a lambda), which are evaluated on each call — useful for multi-tenant setups where the key or algorithm varies per request:
signing_key -> { current_tenant.private_key }
signing_algorithm -> { current_tenant.algorithm }Note
signing_key also accepts an array for key rotation. The first entry is the active key used to sign newly issued ID tokens; the remaining entries are still published in the JWKS so clients can validate tokens signed with a retired key during a rotation window. Callable forms returning an array are also supported.
signing_key [
File.read("config/keys/current.pem"), # active, signs new tokens
File.read("config/keys/previous.pem"), # retired, exposed in JWKS only
]The following settings are optional, but recommended for better client compatibility:
-
auth_time_from_resource_owner- Returns the time of the user's last login, this can be a
Time,DateTime, or any other class that responds toto_i - Used to populate the
auth_timeclaim on the ID Token. - Used as a fallback for
max_ageenforcement whenauth_time_from_sessionis not configured. Note: for multi-session deployments this is insecure (it returns the most recent login on any device), and emits a deprecation warning — preferauth_time_from_sessionbelow.
- Returns the time of the user's last login, this can be a
-
auth_time_from_session-
Returns the time the user authenticated for the current session. Required for correct
max_ageenforcement when the same user can hold multiple concurrent sessions (e.g. PC + smartphone) —auth_time_from_resource_ownercannot distinguish between sessions and would let a stale session inherit a fresh login from another device. -
The block is executed in the controller's scope and receives
(session, request). Return value can be aTime,DateTime, or anything responding toto_i. Returnnilto force reauthentication.# Example: capture auth_time on the session at login, # and surface it here for the OIDC max_age check. auth_time_from_session do |session, _request| session[:auth_time] end
-
-
auth_time_from_access_token-
Derives the
auth_timeclaim from the access token (i.e. per grant) instead of from the resource owner (per user). Useful when you storeauth_timein a custom authentication-context record linked to the access token. -
The block receives the access token and the return value can be a
Time,DateTime, or anything responding toto_i. When configured, it takes precedence overauth_time_from_resource_ownerfor populating theauth_timeclaim on the ID Token. -
Note: this only affects the
auth_timeclaim on the ID Token; it is not used formax_ageenforcement, which still resolves auth_time viaauth_time_from_session/auth_time_from_resource_owner.auth_time_from_access_token do |access_token| access_token.your_custom_authentication_context_record.auth_time end
-
-
reauthenticate_resource_owner- Defines how to trigger reauthentication for the current user (e.g. display a password prompt, or sign-out the user and redirect to the login form).
- Required to support the
max_ageandprompt=loginparameters. - The block is executed in the controller's scope, so you have access to methods like
params,redirect_toetc.
-
select_account_for_resource_owner- Defines how to trigger account selection to choose the current login user.
- Required to support the
prompt=select_accountparameter. - The block is executed in the controller's scope, so you have access to methods like
params,redirect_toetc.
The following settings are optional:
-
expiration- Expiration time after which the ID Token must not be accepted for processing by clients.
- The default is 120 seconds, it can be configured using a value or block.
# config/initializers/doorkeeper_openid_connect.rb Doorkeeper::OpenidConnect.configure do # ... expiration do |resource_owner, application| # You will have to ensure the application model implements an expiration method application.expiration end # ... end
-
protocol- The protocol to use when generating URIs for the discovery endpoints.
- The default is
httpsfor production, andhttpfor all other environments - Note that the OIDC specification mandates HTTPS, so you shouldn't change this for production environments unless you have a really good reason!
-
end_session_endpoint- The URL that the user is redirected to after ending the session on the client.
- Used by implementations like https://github.com/IdentityModel/oidc-client-js.
- The block is executed in the controller's scope, so you have access to your route helpers.
-
discovery_url_options-
The URL options for every available endpoint to use when generating the endpoint URL in the discovery response. Available endpoints:
authorization,token,revocation,introspection,userinfo,jwks,dynamic_client_registration. -
This option requires option keys with an available endpoint and URL options as value.
-
The default is to use the request host, just like all the other URLs in the discovery response.
-
This is useful when you want endpoints to use a different URL than other requests. For example, if your Doorkeeper server is behind a firewall with other servers, you might want other servers to use an "internal" URL to communicate with Doorkeeper, but you want to present an "external" URL to end-users for authentication requests. Note that this setting does not actually change the URL that your Doorkeeper server responds on - that is outside the scope of Doorkeeper.
# config/initializers/doorkeeper_openid_connect.rb Doorkeeper::OpenidConnect.configure do # ... discovery_url_options do |request| { authorization: { host: 'host.example.com' }, jwks: { protocol: request.ssl? ? :https : :http } } end # ... end
-
-
apply_prompt_to_non_oidc_requests-
Whether to honor the
promptauthorization parameter (none,login,consent,select_account) on plain OAuth requests that do not include theopenidscope. -
Defaults to
false, which preserves the historical behavior of silently ignoringpromptoutside of OIDC requests. -
max_ageenforcement remains OIDC-only regardless of this option, since it is defined by OIDC Core.# config/initializers/doorkeeper_openid_connect.rb Doorkeeper::OpenidConnect.configure do # ... apply_prompt_to_non_oidc_requests true # ... end
-