mattcasters opened a new issue, #8333:
URL: https://github.com/apache/hop/issues/8333
## Problem
Hop Web mode `OAUTH2` (`HopOidcAuthFilter`) is **browser SSO**:
authorization code + PKCE + HTTP session cookie. Unauthenticated API clients
get `401 Authentication required (OIDC)`.
That works for the RAP GUI. It does not work for:
- JDBC drivers (e.g. community `jdbc:hop-hsm:` against
`/hop/sourceModelData`)
- curl / Hop Server clients / CI talking to `/hop/*`
- Any plugin servlet used as a data API
JDBC and similar clients cannot complete a redirect or hold a RAP session
cookie. They send `Authorization` on every request.
Mode `BASIC` already accepts `Authorization: Basic` for API clients. Mode
`OAUTH2` has no equivalent.
Related: plugin servlets are also default-denied by
`HopServerEndpointPermissionMapper` until they can register a permission
(separate issue).
## Proposal
Treat Hop Web as an **OAuth2 resource server** for `/hop/*` while keeping
the existing browser login.
### Bearer on the wire
In `HopOidcAuthFilter`, when there is no session principal and the request
has `Authorization: Bearer <token>`:
1. Try a **Hop-issued JDBC token** (HMAC JWT, `iss` = Hop, `aud` =
`hop-jdbc`).
2. Else validate as an **IdP JWT** via the existing `HopOidcClient` JWKS
path (Keycloak, Entra, Google **ID tokens**).
3. Map claims to `HopAuthenticatedPrincipal` with the same role claim as GUI
login, wrap the request.
HTML navigations still redirect to `/login`. API 401 responses should send
`WWW-Authenticate: Bearer`.
Do **not** implement `client_credentials` against Google (Google's web OIDC
client does not issue that grant). Driver-side `client_credentials` remains an
IdP concern (Keycloak, Entra, …).
Google access tokens are often opaque; do not assume they pass JWKS. Accept
Google **ID tokens** (JWT) and Hop-issued HMAC tokens.
### Hop-issued JDBC token
JDBC tools need a token they can paste into a password field. Hop should
mint a short-lived token from an already-authenticated GUI session (the user
signed in with Google/OIDC/Basic once):
- `GET /hop/jdbcToken` (permission `file.view`): session cookie required.
JSON `{"token":"…","expiresIn":3600,"tokenType":"Bearer"}`.
- HMAC-SHA256 with a server secret (`HOP_WEB_JDBC_TOKEN_SECRET` or a file
under the security folder).
- Claims: `sub`, roles, `exp` ~ 1 hour, `aud` = `hop-jdbc`.
- Configuration → Security (or user menu): **Copy JDBC token**.
- Do not persist these tokens in project metadata.
Hop is **not** becoming an OAuth2 authorization server. This is a
first-party API token for tools that cannot do the browser code flow.
## Out of scope
- Device-code / authorization-code inside JDBC drivers.
- A full PAT store with revocation UI (HMAC JWT expiry is enough).
- Changing standalone Jetty Basic on Hop Server.
## Tests
- Bearer IdP JWT (stub JWKS) establishes a principal and passes
`/hop/status` for a role that has `file.view`.
- Invalid / expired Bearer → 401 with `WWW-Authenticate: Bearer`.
- Hop-issued JDBC token round-trip: issue from an authenticated session,
call `/hop/*` with that Bearer.
- Browser HTML without a session still redirects to `/login`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]