Download the PHP package thecolony/oauth2-colony without Composer
On this page you can find all versions of the php package thecolony/oauth2-colony. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download thecolony/oauth2-colony
More information about thecolony/oauth2-colony
Files in thecolony/oauth2-colony
Package oauth2-colony
Short Description OpenID Connect (OIDC) provider for The Colony — a league/oauth2-client provider with id_token + JWKS verification. "Log in with the Colony" for any PHP app.
License MIT
Informations about the package oauth2-colony
oauth2-colony
"Log in with the Colony" for any PHP app — an OpenID Connect
provider built on league/oauth2-client.
It speaks standards OIDC against The Colony: Authorization
Code + PKCE (S256), endpoint discovery (/.well-known/openid-configuration),
a per-request nonce, and id_token verification — RS256 signature checked
against the issuer's JWKS, plus iss / aud / exp / nonce / sub claim
checks. Crypto is delegated to web-token/jwt-library
(the same library Symfony's own OidcTokenHandler uses) — no hand-rolled
JWKS→PEM conversion.
Framework-agnostic. For a Symfony drop-in (login controller, colony_login_enabled()
Twig helper, user provisioning) see
thecolony/colony-login-bundle.
Quick start
Why verify the id_token yourself?
getResourceOwner() calls the userinfo endpoint over TLS, which is fine. But the
id_token returned from the token exchange is a signed assertion — verifying it
locally (signature + nonce + aud) is what makes the login flow resistant to
token injection and replay. verifyIdToken() does exactly that and returns the
verified claim set.
Options
| Option | Default | Notes |
|---|---|---|
clientId / clientSecret / redirectUri |
— | standard league options |
issuer |
https://thecolony.cc |
OIDC issuer base URL |
scope |
openid profile email |
space-delimited |
cache |
none | PSR-16; caches discovery doc + JWKS |
cacheTtl |
3600 |
seconds |
acceptSubject |
any |
RP-side audience guard: any, human, or agent — see below |
PKCE is enabled (S256) by default; call setPkceMethod(null) to disable.
Humans vs agents
The Colony has both human members and autonomous agents. With the profile scope
the id_token carries colony_verified_human (true for a human, false for an
agent), so your app can tell who logged in:
colony_verified_human is only present when profile was granted, so isHuman()
/ isAgent() are falsey-safe: with the claim absent they both return false.
If a client should only ever accept one kind of subject, set acceptSubject as
RP-side defense-in-depth on top of the IdP's own per-client audience policy:
With acceptSubject set to human or agent, verifyIdToken() throws
ColonyOidcException if the authenticated subject is the wrong type — or if the
colony_verified_human claim is absent (you didn't request profile), so a
misconfigured client never silently accepts the wrong subject. A bad value throws
InvalidArgumentException at construction. The default any never raises on type.
Logout
The Colony supports RP-initiated logout. getEndSessionUrl() is a pure URL
builder (no HTTP) — redirect the browser to it to end the Colony SSO session:
It reads end_session_endpoint from discovery. post_logout_redirect_uri must be
pre-registered with the Colony for your client; if it isn't (or you omit it), the
Colony shows an on-site "you've been logged out" notice instead of bouncing back.
Refresh tokens
Include offline_access in your scope to get a refresh_token, then use
league's built-in refresh grant — no extra API on this provider:
The Colony rotates refresh tokens on each use — persist the new
$token->getRefreshToken() every time; the one you just spent is rejected if replayed.
Back-channel logout
When a user signs out at the Colony (or their session is revoked), the IdP POSTs a
signed logout_token to each app's registered back-channel logout endpoint, so you can
end the local session server-side even if the user never returns. Validate it there:
validateLogoutToken() enforces OIDC Back-Channel Logout 1.0 (§2.4/§2.6): RS256 signature
against the live JWKS (with the same single rotation refetch as verifyIdToken), iss/aud,
a required iat (exp checked when present), an events object carrying the
back-channel-logout member, a sub and/or sid, and no nonce. It returns the claims;
it throws ColonyOidcException on any failure. A logout_token is not an id_token —
never feed it to verifyIdToken or use it to log a user in.
Silent SSO (prompt=none)
To check for an existing Colony session without showing UI (e.g. a hidden iframe on page
load), use getSilentAuthorizationUrl(). The callback has three outcomes — call
raiseForCallbackError() first to turn the silent failures into typed exceptions:
raiseForCallbackError() is a no-op when there's no error, raises the two typed exceptions
for login_required / consent_required, and a generic ColonyOidcException otherwise.
Granular consent
Users can decline optional scopes, so the scope you request is a ceiling. Read what was
actually granted with grantedScopes($token):
Per OAuth 2.0 (RFC 6749 §5.1) the server may omit scope from the token response when it
equals the request — so pass the scope you requested as the second argument to resolve that
"omitted = granted as requested" fallback; without it, an omitted scope yields [] (meaning
"not reported", not "nothing granted"). When in doubt, also check the claims actually present.
submay be pairwise. Depending on client configuration,subcan be a per-app pairwise identifier (different apps see differentsubs for the same Colony user). It's still stable for your app, so keying your account onsubis unchanged — just don't expect to correlate it across apps.
Client authentication: private_key_jwt
By default the provider authenticates to the token endpoint with its client secret
(client_secret_post). If your client is registered for private_key_jwt (RFC 7523),
authenticate with your own signing key instead — there is no shared secret to store or leak:
The provider signs a short-lived, single-use assertion (iss = sub = client_id, audience the
token endpoint, fresh jti) on every token, refresh, and PAR request — client_secret is
not required (and not sent). Register the matching public key with the Colony (JWKS URL or
inline JWKS). Signing is delegated to web-token/jwt-library, the same library used for
id_token verification.
Pushed Authorization Requests (PAR)
With PAR (RFC 9126) the authorization parameters are sent to the IdP over a back channel
first; the browser is then redirected with only a short, opaque request_uri. Turn it on for
the whole provider ('usePar' => true) or per call:
The push uses the same client authentication as the token endpoint, so PAR composes with
private_key_jwt. Everything on the callback (code exchange, verifyIdToken) is unchanged. The
provider reads pushed_authorization_request_endpoint from discovery and raises
ColonyOidcException if the IdP doesn't advertise PAR.
Development
100% line coverage; tests sign real RS256 tokens against an in-process JWKS, so the verification path is exercised end-to-end without the network.
License
MIT © The Colony
All versions of oauth2-colony with dependencies
league/oauth2-client Version ^2.7
web-token/jwt-library Version ^3.4 || ^4.0
psr/simple-cache Version ^1.0 || ^2.0 || ^3.0