[
https://issues.apache.org/jira/browse/KNOX-3548?focusedWorklogId=1052561&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1052561
]
ASF GitHub Bot logged work on KNOX-3548:
----------------------------------------
Author: ASF GitHub Bot
Created on: 04/Nov/26 23:42
Start Date: 04/Nov/26 23:42
Worklog Time Spent: 10m
Work Description: smolnar82 opened a new pull request, #1488:
URL: https://github.com/apache/knox/pull/1488
[KNOX-3548](https://issues.apache.org/jira/browse/KNOX-3548) - KnoxIDF:
allow advertising the authorization and client registration endpoints on other
topologies
## What changes were proposed in this pull request?
Two new optional `KNOXIDF` service params tell the discovery documents to
advertise an endpoint on another topology. They work the same way
`token.exchange.topology.name` already does for the token endpoint:
| Param | Moves |
|---|---|
| `authorization.topology.name` | `authorization_endpoint` |
| `client.registration.topology.name` | `registration_endpoint` |
This makes it possible to split the authorization code flow across
topologies that use different authentication: `/authorize` on an SSO-fronted
topology, `/token` on one that accepts client credentials, and client
registration on one that accepts bearer tokens. All of them still publish one
discovery document, from a single topology.
- The params apply to both the OIDC discovery document
(`/.well-known/openid-configuration`) and the RFC 8414 metadata document
(`/.well-known/oauth-authorization-server`, both paths). Both documents are
built by `AuthorizationServerMetadata.buildOAuthMetadata`.
- `issuer` and `jwks_uri` always stay on the current topology.
- `userinfo_endpoint` still follows `token.exchange.topology.name`.
- New package-private `DiscoveryEndpointResolver`: it reads the current
topology and the three params from the servlet context, and resolves each
advertised endpoint URL. Before this change, `DiscoveryResource` and
`AuthorizationServerMetadata` each did their own string substitution.
- A blank param is treated as unset.
- Topology substitution now rewrites only the base URL's `/<topology>/` path
segment. The old `String.replace(current, target)` also rewrote other
occurrences of the name. For example, a topology named `knoxidf` turned
`/gateway/knoxidf/knoxidf/api/v1/token` into
`/gateway/<target>/<target>/api/v1/token`. This changes token and userinfo URLs
only in that broken case.
- Docs: both params are added to `knoxidf/configuration.md`, and the
endpoints tip in `knoxidf/endpoints.md` mentions them.
The params are new, so existing deployments are unaffected.
## How was this patch tested?
- New `DiscoveryEndpointResolverTest`, which runs through both
`DiscoveryResource` and `OAuthServerMetadataResource`:
- all 8 combinations of the three params, set or unset. Each param moves
only its own endpoints, userinfo follows the token param, and `issuer` and
`jwks_uri` stay on the current topology;
- blank params keep every endpoint on the current topology;
- a current topology named `knoxidf`: only the topology segment is
rewritten, not the `knoxidf/api/v1` resource path.
- `OAuthServerMetadataTest` was updated to the new `buildOAuthMetadata`
signature.
- `mvn -pl gateway-service-knoxidf verify` passes: unit tests, checkstyle,
PMD, spotbugs and forbiddenapis.
## Integration Tests
No integration test was added or changed. The existing discovery assertions
in `test_knoxidf.py` cover the default behaviour, with the new params unset and
the token endpoint moved by `token.exchange.topology.name`; they still apply
unchanged. The new params are covered by the unit tests above, which drive the
real JAX-RS resources.
Issue Time Tracking
-------------------
Worklog Id: (was: 1052561)
Remaining Estimate: 0h
Time Spent: 10m
> KnoxIDF: allow advertising the authorization and client registration
> endpoints on other topologies
> --------------------------------------------------------------------------------------------------
>
> Key: KNOX-3548
> URL: https://issues.apache.org/jira/browse/KNOX-3548
> Project: Apache Knox
> Issue Type: Improvement
> Components: KnoxIDF
> Reporter: Sandor Molnar
> Assignee: Sandor Molnar
> Priority: Major
> Fix For: 3.1.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> h3. Background
> KnoxIDF serves its OAuth 2.0 / OIDC endpoints from every topology that
> contains the KNOXIDF service. Deployments often split those endpoints across
> topologies, because each one needs a different authentication provider:
> * {{{}/authorize{}}}: browser-facing, authenticated with SSOCookieProvider
> * {{/token}} and {{{}/userinfo{}}}: called by clients, authenticated with
> JWTProvider (or anonymous for the authorization_code grant)
> * {{{}/client/register{}}}: called by clients, authenticated with a bearer
> JWT
> Each topology also serves the discovery documents
> ({{{}/.well-known/openid-configuration{}}} and
> {{{}/.well-known/oauth-authorization-server{}}}). Those documents must point
> clients at the topology that actually serves each endpoint.
> The token endpoint already supports this. When the
> {{token.exchange.topology.name}} service param is set,
> {{AuthorizationServerMetadata.buildOAuthMetadata}} advertises
> {{token_endpoint}} on that topology. It does this by literally substituting
> the current topology name in the URL. {{DiscoveryResource}} applies the same
> substitution to {{{}userinfo_endpoint{}}}.
> h3. Problem
> Two advertised endpoints have no equivalent setting. Both are always
> advertised on the topology serving the discovery request:
> {noformat}
> metadata.put("authorization_endpoint", baseUrl +
> AuthorizeResource.RESOURCE_PATH);
> metadata.put("registration_endpoint", baseUrl +
> RegistrationResource.RESOURCE_PATH + "/register");
> {noformat}
> *registration_endpoint.* Clients that use dynamic client registration (RFC
> 7591) find the endpoint through discovery. MCP clients are a typical example.
> When discovery is served from an SSO topology, they are sent to a
> registration endpoint that:
> * is protected by SSOCookieProvider, so a programmatic POST without the SSO
> cookie is redirected to the login page;
> * may be blocked by the topology's authorization rules (e.g. PathAclsAuthz
> restricting the topology to {{{}/authorize{}}});
> * uses that topology's {{{}knoxidf.knox.token.ttl{}}}. A short TTL, which
> suits SSO-issued tokens, also makes registered clients expire quickly.
> Clients can't reach a dedicated registration topology through discovery; its
> URL can only be handed to them out of band.
> *authorization_endpoint.* This is the reverse of the token endpoint case.
> Discovery served from the token topology advertises {{/authorize}} on the
> token topology. That topology has no SSO provider, and is typically
> restricted to {{/token}} and {{{}/userinfo{}}}. The token topology's
> discovery document is therefore unusable for the authorization code flow.
> h3. Proposed change
> Add two KNOXIDF service params modelled on
> {{{}token.exchange.topology.name{}}}:
> * {{{}client.registration.topology.name{}}}: the topology on which
> {{registration_endpoint}} is advertised
> * {{{}authorization.topology.name{}}}: the topology on which
> {{authorization_endpoint}} is advertised
> Example (on the SSO topology, {{{}oidc-sso{}}}):
> {code:xml}
> <service>
> <role>KNOXIDF</role>
> <param>
> <name>token.exchange.topology.name</name>
> <value>oidc-token</value>
> </param>
> <param>
> <name>client.registration.topology.name</name>
> <value>oidc-registration</value>
> </param>
> </service>
> {code}
> With this config, discovery served from {{oidc-sso}} would advertise:
> {noformat}
> "authorization_endpoint":
> "https://<host>/gateway/oidc-sso/knoxidf/api/v1/authorize",
> "token_endpoint":
> "https://<host>/gateway/oidc-token/knoxidf/api/v1/token",
> "registration_endpoint":
> "https://<host>/gateway/oidc-registration/knoxidf/api/v1/client/register"
> {noformat}
> Setting {{authorization.topology.name=oidc-sso}} and
> {{client.registration.topology.name=oidc-registration}} on {{oidc-token}}
> makes its discovery document advertise the same endpoints.
> h3. Acceptance criteria
> * With a param set, both {{/.well-known/openid-configuration}} and
> {{/.well-known/oauth-authorization-server}} (at both locations) advertise the
> corresponding endpoint on the configured topology.
> * With the params unset, the advertised {{authorization_endpoint}} and
> {{registration_endpoint}} are identical to today's.
> * The three settings are independent: {{{}token.exchange.topology.name{}}},
> {{client.registration.topology.name}} and {{authorization.topology.name}} can
> each be set without the others, and only the corresponding endpoint changes.
> * Unit tests cover set and unset for each param, for both the OIDC and RFC
> 8414 metadata documents.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)