Shipped drivers#
A driver is registered as a named ZCA utility providing IDriver, and the
utility name is the driver id. Six ship with the package.
Driver id |
Title |
Provider |
|---|---|---|
|
OpenID Connect |
Any conforming OpenID Connect provider. |
|
Plone site |
Another Plone site running the |
|
Keycloak |
A Keycloak realm. Built on |
|
Google, through discovery at an issuer the driver fixes. |
|
|
GitHub |
GitHub OAuth2. Not an OpenID Connect provider. |
|
No external provider: this site emails a single-use signed token. |
Attributes#
Every column is a class attribute on the driver, and every one of them is only a default. What a given deployment trusts a given provider with is a fact about the deployment, so the operator can override each one per provider.
|
|
|
|
|
|
|
|---|---|---|---|---|---|---|
Settings schema |
|
|
|
|
|
|
Endpoints from |
discovery, at an issuer you type |
discovery, at an issuer you type |
discovery, at an issuer you type |
discovery, at the issuer the driver declares |
the four the driver declares |
none |
Default scope |
|
|
|
|
|
— |
Subject read from |
|
|
|
|
|
|
Default userid source |
|
|
|
|
|
|
Trusts |
no |
no |
yes |
yes |
yes |
— |
Default group claim |
|
|
|
none |
none |
none |
Can be linked from a form |
yes |
yes |
yes |
yes |
yes |
no |
email is the only driver a user cannot start a link against from a form: its
subject is an address the user would type, and a free-text box there is a box for
claiming any address at all. Its addresses come from the profile instead.
Which settings each schema carries#
This is what decides which fields a provider's form shows. A driver on
IOAuth2Settings has no issuer field and no group fields at all.
Schema |
Extends |
Adds |
|---|---|---|
|
|
nothing |
|
|
|
|
|
|
|
|
|
|
|
nothing but a different |
|
|
nothing but a different |
|
|
|
Two consequences worth reading off that table:
googleandgithubhave no group settings. Not a group claim you can name, not an allowed-groups list, not a sync switch. Neither provider sends groups this package can read.emailhas no account settings. Nocreate_user, noauto_link_by_email, notrust_email_verification. A missingcreate_userreads asTrue, so anemailprovider always creates accounts.
See Settings for each field's type and default, and The provider form for how they are arranged in the control panel.
Default property maps#
Seeded into a new provider's attribute mapping, written against the normalized claim names rather than any one provider's.
Driver |
Map |
|---|---|
|
|
|
that, plus |
|
that first row, plus |
|
empty |
A map never writes an address or a portrait, see Settings, so no driver
seeds a row for either. Both arrive on a login regardless: an
address is appended to the profile's own list, and a portrait is fetched from
the picture_url claim when sync_portraits is on.
No driver maps username. Providers publish it; a Profile has no such field.
Default icons#
Every shipped driver has a login-button icon. A provider with no icon of its own is drawn with its driver's, and an icon uploaded on the provider replaces it.
Driver |
File |
Copied from |
Licence |
|---|---|---|---|
|
|
|
MIT |
|
|
|
MIT |
|
|
|
MIT |
|
|
Volto, |
MIT |
|
|
Volto, |
MIT |
|
|
Volto, |
MIT |
The default is resolved when a provider is drawn, in @login-providers and
@identities, and never stored. The provider's record, the control panel form
and an export carry only an uploaded icon. @identity-drivers serves each
driver's default, and the form's Icon field shows it until one is uploaded.
A default passes through the same sanitizer as an upload. A third-party driver
names its own with icon_resource, as package:path. One that does not resolve,
or is not an SVG document, is logged and drawn as no icon.
Driver notes#
githubNot an OpenID Connect provider: it publishes no discovery document, so the driver declares its four endpoints outright.
GET /useromits the address of anybody who marked it private and carries noemail_verifiedat all, so the driver namesGET /user/emailsas an enrichment endpoint and the flow fetches it after userinfo. That call is best-effort: a narrowed scope answers 403, and a login is not the moment to fail over an address. Every address on the account goes onto the person's profile, the account's own primary first.googleThe driver declares the issuer,
https://accounts.google.com, rather than asking for it. There is nothing to configure and nothing to get wrong. Its userinfo carries a name, an address and a picture, and nothing a Profile's other three fields could hold, which is why its map has one row.oidc-genericThe one driver that declares neither endpoints nor an issuer: both come from the operator, because "any conforming provider" is exactly the case where the package knows nothing in advance. Its map has one row for the same reason:
websiteandaddress.formattedare registered OIDC claims, but whether a given provider fills them in is not something a generic driver can know.plone-identityA peer is a conforming OIDC provider and gets no special path through the flow. What the driver carries is the configuration a peer can be known in advance to want: the
addressscope, a map for every claim the peer actually releases, and the peer'spreferred_usernameas the local userid, so one person is recognisable by the same name across the federation.keycloakLike a peer, a realm is a conforming OIDC provider and gets no special path through the flow. The driver carries the realm's
preferred_usernameas the local userid, and trusts itsemail_verified, since a realm is usually run by the organization running the site. Its scope and map are the generic ones: underopenid email profilea default realm releases a name, a username and an address, and nothing a Profile's other three fields could hold. Its issuer is the realm URL,https://<server>/realms/<realm>; the server root serves no discovery document.emailSee below.
To add a driver for a provider not listed here, see Write a driver.
Group claims#
A driver declares whether its providers assert group membership, and that declaration is what offers the group map in the control panel. A driver with no group claim offers no field to name one, and a group map stored against such a provider grants nothing rather than guessing at a claim name.
groups is not a registered OIDC claim. It is the name Keycloak, Okta and Entra
all use, and the one this package's own [server] layer releases. Set a dotted
path for a provider that nests them, such as realm_access.roles.
Mapping and revocation are covered in Map provider groups.
The email driver#
Property |
Value |
|---|---|
Token lifetime |
At most fifteen minutes, whatever |
Reuse |
Single use. The token is burned server side. |
Rate limit |
Per address and per IP. |
Response to an unknown address |
Identical to the response for a known address. |
The rate limit applies per IP as well as per address because limiting per address alone misses the enumeration attack, which uses a fresh address every time. The send endpoint answers identically whether or not the address belongs to an account: a different answer would be an account-existence oracle.
A magic-link sign-in is the only email verification this package trusts for linking decisions. See About email verification.
Two kinds of link#
Link |
Asked for from |
Effect |
Redeemed at |
|---|---|---|---|
Sign-in |
The login page |
Signs its holder in |
|
Confirmation |
Sign-in methods |
Adds the address to the account that asked for it, and signs nobody in |
its own endpoint |
Each endpoint accepts only the purpose it handles, so neither link can be redeemed as the other.
A confirmation link has to be opened while the account that asked for it is still signed in. Opening it as somebody else, or as nobody, is refused—and the link is spent either way.