Closed mmoayyed closed 7 years ago
@mmoayyed How complicated was your customization code? My initial feeling is that we might not want to add support directly for Boot if it's not too hard to do with a customizer.
It was quite simple actually; I believe our use case had to do with X509 authentication or some such.
We have also added a few other customizations to enable AJP as well as the ability to have the container listen on yet another port other than server.port
based on available recipes. I'd be happy to contribute these back as well if you find usefulness in them. Less code for us, and perhaps more capabilities for Boot?
PS Pinging @hdeadman as well, since he was the one who proposed the request initially to me and might be able to explain the case better than I could.
I'm not sure to be honest. It's a difficult balance as to when we add direct support or when we recommend the use of a customizer. More recently we've tried to shy away from any change what can't be uniformly applied across all servlet containers.
It rather depends on how common the use-case is and if it's something we think many other users will benefit from. If it's not an oft-requested feature we'll generally leave it out of Boot (less for us to maintain and test).
I submited a pull request to CAS https://github.com/apereo/cas/pull/2484 that only supported Tomcat because I figured that if in the future, someone came to CAS and requested similar support for Jetty or Undertow, at that point it might be worth requesting that the feature be added to Spring boot.
I don't know what the Jetty equivalent of a valve is but the SSLValve could probably be implemented as a servlet filter since it just takes a base 64 encoded certificate off of an HTTP header and puts a Certificate object on the request where the servlet spec expects it to be. I remember someone complaining that it's parsing logic wasn't very forgiving but it works if you set the header right on the load balancer.
This is what haproxy config looks like, it requests client cert and puts cert on header in format that SSLValve can parse.
frontend web-vip
bind 192.168.2.10:443 ssl crt /var/lib/haproxy/certs/www.example.com.pem ca-file /var/lib/haproxy/certs/ca.pem verify optional
mode http
acl www-cert ssl_fc_sni if { www.example.com }
acl empty-path path /
http-request redirect location /cas/ if empty-path www-cert
http-request del-header ssl_client_cert unless { ssl_fc_has_crt }
http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt }
acl cas-path path_beg -i /cas
reqadd X-Forwarded-Proto:\ https
use_backend cas-pool if cas-path
backend cas-pool
option httpclose
option forwardfor
cookie SERVERID-cas insert indirect nocache
server cas-1 192.168.2.10:8080 check cookie cas-1
Important line is:
http-request set-header ssl_client_cert -----BEGIN\ CERTIFICATE-----\ %[ssl_c_der,base64]\ -----END\ CERTIFICATE-----\ if { ssl_fc_has_crt }
On a Big-IP F5 SSL Proxy you can write in an i-rule:
HTTP::header insert "ssl_client_cert" [X509::whole [SSL::cert 0]]
and that will also be handled by the SSLValve.
If you are doing X509 authentication, the client cert request usually happens at the proxy/load balancer and communicating it to the app server via an HTTP header is a fairly easy way to get it there if the app server knows how to reconstitute it.
Does spring boot ever add filters to the application? If so, could the SSLValve be turned into a filter (that ran pre-security filters) so it would work on all containers?
Having discussed this a little we'd prefer to not add direct support at this time. The customizers provide a nice escape hatch and we'd like to keep the surface area of the code we need to support as small as possible.
Thanks anyway for the suggestion.
Hello,
I looked around in the docs/code and failed to find a reference to this particular request, so here it goes: is Spring Boot interested in receiving a pull request that adds support for Apache Tomcat's SSL_Valve?
We are currently customizing the embedded container instance ourselves (via Boot 1.5.2) to insert the valve, and I am wondering if this might be something you may want to offer via Boot directly.
Thank you.