You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, we are able to implement Mutual TLS Authentication (mTLS) via configuring the various backends (e.g. Jetty). However, once authenticated, we are not able to utilise http4k (E.g. implement our own custom Filters) to perform authorisation as the certificate (or its principal/ subject) is not passed to the Request object.
Feature Request
Add support to allow Filters to retrieve the certificate used for authentication (e.g. via the Request object, or other possible means). The certificate is available from the underlying web server abstraction, for example in Jetty, it is available via a call to the HttpServletRequest#getAttribute method, using javax.servlet.request.X509Certificate as the key.
With this enhancement, it will allow us to write more default Authentication Filters like CertificateAuthenticationFilter, that will allow users to configure authentication via X509Certificate principal.
The text was updated successfully, but these errors were encountered:
Thanks for the request. FYI, we have implemented MTLS on a couple of http4k projects in the past - so you do already can do it at a push. Both involve implementing custom ServerConfig to get the behaviour you want:
You can use a RequestContexts and RequestContextKey to attach whatever you want to the request and then access it downstream in a Filter. This isn't particularly neat in terms of server construction because of the bleeding of the RequestContextKey between the ServerConfig and the
If you just need the certificate fingerprint for auth, that can be computed and extracted from the certificate and then added to the request as a custom "X-" header.
Currently we are trying to do it by implementing our own HttpHandlerServletAdapter and then rewiring the corresponding up stream code so that we can pass our own HttpHandlerServlet to the Jetty handler, is this what you meant by 2.?
We also tried a less invasive way where we add a ServletFilter to the JettyHandler. However, the issue with this approach was that we had to deal with HttpServletRequest which does not allow us to rewrite the headers. The workaround was to return a subclass of the HttepServletRequestWrapper and override the related getHeader, getHeaders, and getHeaderNames methods to mimic adding of headers. This feels hackish, hence we are trying to find a better way.
It seems that combining this ServletFilter method with RequestContexts is what is suggested in 1 but we are not sure what to use as a key for each request (i.e. how do we obtain a RequestContextKey from a HttpServletRequest?)
Just wondering whats the best way/ workaround at the moment?
For 1 (and using SunHttp as an example) something like this works. It's not particularly pretty as it introduces some dependencies between construction of the server and the app, but it will get you there.
The key here is that you don't need to rewrite the Jetty headers - just the Http4k headers - which will be done automatically in the case above - so you just need to "import" the RequestContextKey. There is also a way to reduce the key being passed at the expense of randomness by hardcoding the identifier instead (but the store will still need to be passed): val key = RequestContextKey.required<MyX509Cert>(store, "cert")
For 2 - a similar thing - just compute the certificate fingerprint inside your custom jetty and then add an http4k header which is passed downstream to the filters.
Background
Currently, we are able to implement Mutual TLS Authentication (mTLS) via configuring the various backends (e.g. Jetty). However, once authenticated, we are not able to utilise http4k (E.g. implement our own custom Filters) to perform authorisation as the certificate (or its principal/ subject) is not passed to the Request object.
Feature Request
Add support to allow Filters to retrieve the certificate used for authentication (e.g. via the Request object, or other possible means). The certificate is available from the underlying web server abstraction, for example in Jetty, it is available via a call to the
HttpServletRequest#getAttribute
method, usingjavax.servlet.request.X509Certificate
as the key.Prior Art
Micronaut's
HttpRequest
has a method to retrieve the client certificate: HttpRequest#getCertificateFuture Work
With this enhancement, it will allow us to write more default Authentication Filters like CertificateAuthenticationFilter, that will allow users to configure authentication via X509Certificate principal.
The text was updated successfully, but these errors were encountered: