KemalIdentity::OIDC::Provider
One OpenID Connect provider, as a client of it.
docs/00-scope.md puts being an authorization server permanently outside this shard. This
is the other side: the application redirects somebody to Google or Okta or an internal
provider, and gets back an assertion about who they are.
Authorization Code with PKCE, and nothing else
No implicit flow, no hybrid, no resource-owner password grant. The implicit flow puts a
token in a URL fragment, where it lands in browser history and in any Referer that leaks;
the password grant asks your application to handle somebody else's password, which is the
thing federating was supposed to avoid. Both are discouraged by the OAuth 2.1 draft and
neither is expressible here.
PKCE is not optional either, including for a confidential client with a secret. It costs a hash and it closes authorization-code interception, which a client secret does not: the secret proves the client, and PKCE proves the request came from the same place the code was issued to.
Constants
Everything Client#authorize puts in the query string itself.
Constructors
Instance methods
Extra query parameters to add to the authorization request, for the things a provider wants
and no standard names: Google's hd, Okta's login_hint, Azure's domain_hint.
Allowlisted by exclusion, and refused at boot
RESERVED below is every parameter Client#authorize builds itself, and a key matching one
of them raises ConfigurationError at construction rather than being silently dropped or
silently winning. Four of them — state, nonce, code_challenge, code_challenge_method
— are the flow's security, and an application that could overwrite them could turn PKCE off
by configuration. The rest name the client and where the code comes back to.
prompt is reserved too, and is not a security value: Client#authorize(prompt:) sets it,
and two prompt parameters in one query string is a request the provider gets to interpret
however it likes.
Values are escaped by URI::Params, so nothing here can inject a separator.
The client secret, for a confidential client. nil for a public one.
A public client — a CLI, a desktop application — has nowhere to keep a secret, and PKCE is what protects it. A server-side web application is confidential and should have one.
Redacted: a config dump in a crash report must not print a client secret.
The iss every ID token from this provider must carry, compared exactly.
Not a base URL to build others from and not a display name — it is the identity of the
party whose assertions you are about to believe, and half of the (issuer, subject) pair
that names an external account forever.
Where the provider's signing keys come from. Normally a JWT::JWKS over its
jwks_uri, so a rotation is picked up without a restart.
Where the provider sends the browser back.
Registered with the provider and compared by it exactly, character for character — which is the check that stops an attacker registering a lookalike path and collecting codes. It is sent again at the token exchange for the same reason.