From 3edee485dd37817a66c1c7e329a35b750f0e6b5a Mon Sep 17 00:00:00 2001 From: micolous <micolous+gh@gmail.com> Date: Tue, 25 Feb 2025 12:53:53 +1000 Subject: [PATCH] address webfinger doc feedbacks (#3446) --- book/src/integrations/oauth2.md | 101 ++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/book/src/integrations/oauth2.md b/book/src/integrations/oauth2.md index 9a9bbad6c..5c395293f 100644 --- a/book/src/integrations/oauth2.md +++ b/book/src/integrations/oauth2.md @@ -85,7 +85,7 @@ URL **(recommended)** <dt> -[WebFinger URL **(discouraged)**](#webfinger) +[WebFinger URL](#webfinger) **(discouraged)** </dt> @@ -162,7 +162,7 @@ Token endpoint <dt> -OpenID Connect issuer URI +OpenID Connect Issuer URL </dt> @@ -458,58 +458,83 @@ Each client has unique signing keys and access secrets, so this is limited to ea ## WebFinger -[WebFinger](https://datatracker.ietf.org/doc/html/rfc7033) provides a mechanism -for discovering information about people or other entities. It can be used by an -identity provider to supply OpenID Connect discovery information. +[WebFinger][webfinger] provides a mechanism for discovering information about +entities at a well-known URL (`https://{hostname}/.well-known/webfinger`). -Kanidm provides -[an Identity Provider Discovery for OIDC URL](https://datatracker.ietf.org/doc/html/rfc7033#section-3.1) -response to all incoming WebFinger requests, using a user's SPN as their account -ID. This does not match on email addresses as they are not guaranteed to be -unique. +It can be used by a WebFinger client to +[discover the OIDC Issuer URL][webfinger-oidc] of an identity provider from the +hostname alone, and seems to be intended to support dynamic client registration +flows for large public identity providers. -However, WebFinger has a number of flaws which make it difficult to use with -Kanidm: +Kanidm v1.5.1 and later can respond to WebFinger requests, using a user's SPN as +part of [an `acct` URI][rfc7565] (eg: `acct:user@idm.example.com`). While SPNs +and `acct` URIs look like email addresses, [as per RFC 7565][rfc7565s4], there +is no guarantee that it is valid for any particular application protocol, unless +an administrator explicitly provides for it. -* WebFinger assumes that the identity provider will give the same `iss` - (Issuer) for every OAuth 2.0/OIDC client, and there is no standard way for a - WebFinger client to report its client ID. +When setting up an application to authenticate with Kanidm, WebFinger **does not +add any security** over configuring an OIDC Discovery URL directly. In an OIDC +context, the specification makes a number of flawed assumptions which make it +difficult to use with Kanidm: - Kanidm uses a *different* `iss` (Issuer) value for each client. +* WebFinger assumes that an identity provider will use the same Issuer URL and + OIDC Discovery document (which contains endpoint URLs and token signing keys) + for *all* OAuth 2.0/OIDC clients. -* WebFinger requires that this be served at the *root* of the domain of a user's + Kanidm uses *client-specific* Issuer URLs, endpoint URLs and token signing + keys. This ensures that tokens can only be used with their intended service. + +* WebFinger endpoints must be served at the *root* of the domain of a user's SPN (ie: information about the user with SPN `user@idm.example.com` is at - `https://idm.example.com/.well-known/webfinger`). + `https://idm.example.com/.well-known/webfinger?resource=acct%3Auser%40idm.example.com`). - Kanidm *does not* provide a WebFinger endpoint at its root URL, because it has - no way to know *which* OAuth 2.0/OIDC client a WebFinger request is associated - with, so could report an incorrect `iss` (Issuer). + Unlike OIDC Discovery, WebFinger clients do not report their OAuth 2.0/OIDC + client ID in the request, so there is no way to tell them apart. - You will need a load balancer in front of Kanidm's HTTPS server to redirect - requests to the appropriate `/oauth2/openid/:client_id:/.well-known/webfinger` - URL. If the client does not follow redirects, you may need to rewrite the - request in the load balancer instead. + As a result, Kanidm *does not* provide a WebFinger endpoint at its root URL, + because it could report an incorrect Issuer URL and lead the client to an + incorrect OIDC Discovery document. + + You will need a load balancer in front of Kanidm's HTTPS server to send a HTTP + 307 redirect to the appropriate + `/oauth2/openid/:client_id:/.well-known/webfinger` URL, *while preserving all + query parameters*. For example, with Caddy: + + ```caddy + # Match on a prefix, and use {uri} to preserve all query parameters. + # This only supports *one* client. + example.com { + redir /.well-known/webfinger https://idm.example.com/oauth2/openid/:client_id:{uri} 307 + } + ``` If you have *multiple* WebFinger clients, it will need to map some other property of the request (such as a source IP address or `User-Agent` header) to a client ID, and redirect to the appropriate WebFinger URL for that client. * Kanidm responds to *all* WebFinger queries with - [an Identity Provider Discovery for OIDC URL](https://datatracker.ietf.org/doc/html/rfc7033#section-3.1), - **regardless** of what - [`rel` parameter](https://datatracker.ietf.org/doc/html/rfc7033#section-4.4.4.1) - was specified. - - This is to work around - [a broken client](https://tailscale.com/kb/1240/sso-custom-oidc) which doesn't - send a `rel` parameter, but expects an Identity Provider Discovery issuer URL - in response. + [an Identity Provider Discovery for OIDC URL][webfinger-oidc], **ignoring** + [`rel` parameter(s)][webfinger-rel]. If you want to use WebFinger in any *other* context on Kanidm's hostname, you'll need a load balancer in front of Kanidm which matches on some property of the request. -Because of the flaws of the WebFinger specification and the deployment -difficulties they introduce, we recommend that applications use OpenID Connect -Discovery or OAuth 2.0 Authorisation Server Metadata for client configuration -instead of WebFinger. + WebFinger clients *may* omit the `rel=` parameter, so if you host another + service with relations for a Kanidm [`acct:` entity][rfc7565s4] and a client + *does not* supply the `rel=` parameter, your load balancer will need to merge + JSON responses from Kanidm and the other service(s). + +Because of these issues, we recommend that applications support *directly* +configuring OIDC using a Discovery URL or OAuth 2.0 Authorisation Server +Metadata URL instead of WebFinger. + +If a WebFinger client only checks WebFinger once during setup, you may wish to +temporarily serve an appropriate static WebFinger document for that client +instead. + +[rfc7565]: https://datatracker.ietf.org/doc/html/rfc7565 +[rfc7565s4]: https://datatracker.ietf.org/doc/html/rfc7565#section-4 +[webfinger]: https://datatracker.ietf.org/doc/html/rfc7033 +[webfinger-oidc]: https://datatracker.ietf.org/doc/html/rfc7033#section-3.1 +[webfinger-rel]: https://datatracker.ietf.org/doc/html/rfc7033#section-4.3