The OpenID Connect authentication is very similar to its authorization counterpart in OAuth 2.0, the single difference being that the token generation can include the generation of an ID token, alongside the access token.
When the Relying party requires a secure token with claims about the authentication of the end-user.
plugin :rodauth do
enable :oidc
oauth_jwt_keys("RS256" => OpenSSL::PKey::RSA.new("/path/to/privkey.pem"))
oauth_jwt_public_keys("RS256" => OpenSSL::PKey::RSA.new("/path/to/pubkey.pem"))
# you should define all scopes relevant for your use case, openid and non-openid.
# An OpenID provider is first-and-foremost an OAuth Authorization Server, and can
# can authorize other realms beyond what OpenID defines
oauth_application_scopes %w[openid email profile some_other_non_openid_scope]
# callback to retrieve normal claims.
# https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims P. 5.4
get_oidc_param do |account, oidc_claim|
case oidc_claim
when :email
# return the email
when :email_verified
# returns true or false
# ... and so on
end
end
end
The URI under which the journey begins is (by default, like in OAuth 2.0) /authorize
. It supports the same parameters as the OAuth 2.0 authorization endpoint, along with extra parameters (read the ID Token RFC 3.1.2.1 for a more detailed description):
client_id
: used to select the relying party, or client application;redirect_uri
: used to validate and indicate where the user agent should redirect the authenticated user;scope
: whitespace-separated permission scopes to set on the tokens (if not passed, the grant will be generated from the client application scopes; if passed, they need to be all or a subset of the client application scopes). For OpenID, the “openid” scope is mandatory (extra OpenID scopes: profile
, email
, address
, or the special offline_access
, if a refresh token is to be generated); other non-OpenID scopes can be passed;state
: (optional) opaque string value, can be used by the relying party to maintain state between the request and callback for redirection validation;response_type
: identifies the type of authentication flow;nonce
: (optional) opaque value which will be associated with the ID token as an extra claim, and can be used by the relying party to verify whether an ID token was generated from a particular authentication session.prompt
: (optional) one of none
, login
, consent
or select-account
, signals what the authorization server should do before allowing the user to submit authorization, such as (respectively) relogin, grant consent, or explicitly select an account (NOTE: in order to use the select-account
option, make sure you install and enable the select_account
feature)display
(optional): specifies how the authentication session is displayed (rodauth-oauth
does not use it, but the integrator can use it to pick up a different (i.e. embed or mobile friendly) layout.max_age
(optional): when passed, is used as a threshold which, if surpassed by the existing authenticated session lifetime, forces the user to relogin (it can be verified by the relying party using the "auth_time"
claim available in the ID Token).ui_locales
(optional): whitespace-separated list of language codes (ordered by preference); if the i18n
feature is installed and enabled, it’ll pick up the language for which translations are available, by order of preference.claims_locales
(optional): whitespace-separated list of language codes, for which ID token claims can be translated (if get_oid_param
or get_additional_param
are defined with a 3rd argument, it’ll be passed the locale code, for which you can provide a translation);acr_values
(optional): whitespace-separated list of Authentication Context references, which the OpenID provider can use in the processing of the Authentication request (the used acr values will be set as extra claims in the ID Token). rodauth-oauth
provides support for the EAP defined ACR values "phr"
and "phrh"
, whereby:
"phr"
is set in "acr_values"
and a 2 factor rodauth
feature (such as otp or sms_codes) is loaded, it’ll require it when authenticating the user with OpenID Provider."phr"
is set in "acr_values"
and rodauth
“webauthn_login” feature is loaded, it’ll require it when authenticating the user with OpenID Provider.require_acr_value
callback.claims
(optional): used to enable specific claims to be returned from the UserInfo Endpoint and/or in the ID Token.registration
(optional): used for enable specific claims to be returned from the UserInfo Endpoint and/or in the ID Token.Example: https://oauth-server.com/authorize?client_id=23uhu23d89u3298du21j38q&redirect_uri=https%3A%2F%2Fclient.com%2Fcallback&scope=openid+email+profile.name+bricks.build+bricks.destroy&nonce=23r0rif3j0923j
The :oidc
feature also supports secured authorization requests.
Note: the offline_access
scope is also supported.
The ID token is a security token containing the claims defined by the OpenID spec, such as email, full name, phone number, etc. Its usage is restricted to providing authentication claims only, it should not be used when requesting anything from resource servers (that’s what the access token is for).
It supports the Standard Claims via the get_oidc_param
function, which can be used by the integration to provide the value, as per the example above. If you pass it a standard claim in the scope, the extended claims will be exposed to get_oidc_param
, i.e with scope=openid email
as scope param, both the email
and email_verified
claims will be requested via get_oidc_param
.
Distributed and aggregated claims can be implemented by overriding the fill_with_account_claims
auth method:
plugin :rodauth do
enable :oidc
fill_with_account_claims do |claims, account, scopes, claims_locales|
super(claims, account, scopes, claims_locales)
if scopes.include?("profile") # if this is what you want to filter it by
claims[:_claim_names] = {
"payment_info" => "src1",
"shipping_address" => "src1",
"credit_score" => "src2"
}
claims[:_claim_sources] = {
"src1" => {"endpoint" => "https://bank.example.com/claim_source"},
"src2": {"endpoint" => "https://creditagency.example.com/claims_here",
"access_token" => "ksj3n283dke"}
}
end
end
The ID token is signed, and optionally encrypted. If the Provider exposes multiple signing JWKs, client applications can choose which signing algorithm their ID tokens should be signed with, by setting the client application attribute oauth_applications_id_token_signed_response_alg_column
(encryption options for the same token are oauth_applications_id_token_encrypted_response_alg_column
and oauth_applications_id_token_encrypted_response_enc_column
).