Spring 通过 Apache 反向代理启动证书认证
Spring Boot certificate authentication via Apache reverse proxy
我已成功将 Apache (2.4.7) 配置为需要客户端证书,并且作为反向代理将证书中的信息转发到 Tomcat 8 服务器。
当尝试使用 Spring Boot 完成相同的操作时,它失败了
The proxy server received an invalid response from an upstream server
The proxy server could not handle the request GET /myapp
和 returns HTTP 502 错误代码。
相关的工作 Tomcat 配置是:
<Connector SSLEnabled="true" clientAuth="want" keyAlias="myalias"
keystoreFile="mystore.jks" keystorePass="mypassword" maxThreads="150"
port="8443" protocol="HTTP/1.1" scheme="https" secure="true"
sslProtocol="TLS" truststoreFile="mystore.jks" truststorePass="mypassword"/>
Spring 引导 application.properties 文件的相关部分不起作用:
server.context-path=/myapp
server.port=8443
server.ssl.enabled=true
server.use-forward-headers=true
server.ssl.protocol=TLS
server.ssl.client-auth=need
server.ssl.key-alias=myalias
server.ssl.key-store=/path/to/mykeystore.jks
server.ssl.key-store-password=mypassword
server.ssl.key-password=mypassword
server.ssl.trust-store=/path/to/mykeystore.jks
server.ssl.trust-store-password=mypassword
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.port-header=x-forwarded-port
注意,直接访问应用程序(即请求https://myapp.company.tld:12345/myapp) it works just fine, but using the reverse proxy (i.e. https://proxy-load-balancer.company.tld:12345/myapp)会抛出上述错误。
端口差异(12345 与配置的 8443)是由于中间 Docker 层:反向代理和应用程序都在容器中运行,并且它们的开放端口(Apache 为 443,[Apache 为 8443) =29=] Boot) 映射到不同的端口,即 12345.
好的,所以这一切都解决了。首先,这个 Spring 安全设置
server.ssl.client-auth=need
将总是强制你的嵌入式Tomcat请求证书,所以在客户端=>反向代理=>Tomcat情况下你不会'除非您使用 AJP,否则无法进行身份验证,对此我不确定。
但事实证明,使用
server.ssl.client-auth=want
允许进一步处理您的请求,人们通常做的是在反向代理级别处理证书并将一些信息转发到后端服务器(Tomcat、Jetty 等)。
最后,开发人员不得不调整他们的 Spring 引导应用程序来处理后一种操作模式,即从转发的 HTTP 请求中提取数据 header 并根据该数据继续进行身份验证.
我已成功将 Apache (2.4.7) 配置为需要客户端证书,并且作为反向代理将证书中的信息转发到 Tomcat 8 服务器。
当尝试使用 Spring Boot 完成相同的操作时,它失败了
The proxy server received an invalid response from an upstream server
The proxy server could not handle the request GET /myapp
和 returns HTTP 502 错误代码。
相关的工作 Tomcat 配置是:
<Connector SSLEnabled="true" clientAuth="want" keyAlias="myalias"
keystoreFile="mystore.jks" keystorePass="mypassword" maxThreads="150"
port="8443" protocol="HTTP/1.1" scheme="https" secure="true"
sslProtocol="TLS" truststoreFile="mystore.jks" truststorePass="mypassword"/>
Spring 引导 application.properties 文件的相关部分不起作用:
server.context-path=/myapp
server.port=8443
server.ssl.enabled=true
server.use-forward-headers=true
server.ssl.protocol=TLS
server.ssl.client-auth=need
server.ssl.key-alias=myalias
server.ssl.key-store=/path/to/mykeystore.jks
server.ssl.key-store-password=mypassword
server.ssl.key-password=mypassword
server.ssl.trust-store=/path/to/mykeystore.jks
server.ssl.trust-store-password=mypassword
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.port-header=x-forwarded-port
注意,直接访问应用程序(即请求https://myapp.company.tld:12345/myapp) it works just fine, but using the reverse proxy (i.e. https://proxy-load-balancer.company.tld:12345/myapp)会抛出上述错误。
端口差异(12345 与配置的 8443)是由于中间 Docker 层:反向代理和应用程序都在容器中运行,并且它们的开放端口(Apache 为 443,[Apache 为 8443) =29=] Boot) 映射到不同的端口,即 12345.
好的,所以这一切都解决了。首先,这个 Spring 安全设置
server.ssl.client-auth=need
将总是强制你的嵌入式Tomcat请求证书,所以在客户端=>反向代理=>Tomcat情况下你不会'除非您使用 AJP,否则无法进行身份验证,对此我不确定。
但事实证明,使用
server.ssl.client-auth=want
允许进一步处理您的请求,人们通常做的是在反向代理级别处理证书并将一些信息转发到后端服务器(Tomcat、Jetty 等)。
最后,开发人员不得不调整他们的 Spring 引导应用程序来处理后一种操作模式,即从转发的 HTTP 请求中提取数据 header 并根据该数据继续进行身份验证.