Sandor Molnar created KNOX-3454:
-----------------------------------
Summary: Add integration-test coverage that exercises the
ClientCert authentication provider (X.509 principal extraction) behind inbound
mTLS
Key: KNOX-3454
URL: https://issues.apache.org/jira/browse/KNOX-3454
Project: Apache Knox
Issue Type: Task
Components: CI
Affects Versions: 3.1.0
Reporter: Sandor Molnar
Fix For: 3.1.0
*Background*
Knox's {{ClientCert}} authentication provider authenticates a caller by reading
the client X.509 certificate the servlet container places on the request during
an inbound mTLS handshake, deriving a principal from it (full subject DN, or
the CN when {{{}client.cert.principal.attribute.name=CN{}}}), and running the
rest of the filter chain as that Subject.
Today nothing - unit or integration - drives a real certificate through this
filter:
- The CI mTLS test .github/workflows/tests/test_single_eku_mtls.py asserts
only that the TLS handshake completes / is enforced at the transport layer (its
own docstring: "Only the handshake is asserted (not the HTTP status)")
- No CI topology wires the {{ClientCert}} provider; grepping
{{.github/workflows/build/conf/topologies/*.xml}} for ClientCert returns nothing
- The only unit test, {{{}ClientCertDeploymentContributorTest{}}}, checks
{{ServiceLoader}} registration and that init/finalize don't throw; it never
exercises {{doFilter}} against a request.
*Why now*
The Jakarta / Jetty-12-EE10 migration (see KNOX-3238) had to change this
request-attribute key from {{javax.servlet.request.X509Certificate}} to
{{jakarta.servlet.request.X509Certificate}} (Jetty 12 EE10 publishes the client
cert under the {{jakarta.*}} name). Under the stale key the lookup silently
returns null and client-cert authentication (and the cert-bound path in
{{{}TokenResource{}}}) breaks at runtime. Because no test exercises this code
path, a fully green CI run did not catch it - it was found by hand. This ticket
closes that gap so any future regression on this line fails CI.
*Proposed change*
Extend the existing single-EKU mTLS CI stack (already provisioned with a
trusted client cert and run unconditionally on every PR) so a test proves Knox
authenticates a principal from the certificate, not just that TLS negotiates:
1. New topology {{.github/workflows/build/conf/topologies/clientcert.xml}}
wiring:
- authentication / ClientCert, with param
client.cert.principal.attribute.name=CN
- identity-assertion / Default
- service KNOX-AUTH-SERVICE - its {{preauth}} endpoint echoes the
authenticated actor id in a response header ({{{}x-knox-actor-username{}}})
with HTTP 200; the same mechanism {{test_knoxauth_preauth_and_paths.py}}
already relies on.
2. New test case (extend {{{}test_single_eku_mtls.py{}}}, reusing the
already-mounted {{KNOX_CLIENT_CERT}} / {{KNOX_CLIENT_KEY}} PEM fixtures whose
subject is {{{}CN=knox-client{}}}):
- {{GET}} the new topology's preauth endpoint with the client cert -> assert
HTTP 200 and the {{x-knox-actor-username}} header equals {{{}knox-client{}}}.
This proves the cert was read out of the servlet request and turned into a
principal.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)