使用Nginx和Tomcat Web应用程序进行TLS客户端身份验证
问题描述:
我有一个Tomcat 8 Web应用程序,它在服务器上的端口8080上运行。任何到端口443的传入请求都会使用Nginx转发到localhost:8080以提供Web应用程序。使用Nginx和Tomcat Web应用程序进行TLS客户端身份验证
我试图建立相互认证&然后解析用于应用程序认证的客户端证书。这些信息将被应用程序用来决定用户是否应具有admin
或user
权限。客户证书将在通用名称(CN)字段中携带字符串admin
或user
。
我能够实现相互认证&下面是当前的nginx ssl.conf但是问题在于cert信息没有传递给tomcat web应用程序来解析数据。有没有在nginx中传递客户端证书数据的方法,所以tomcat8应用程序可以使用它?
server {
listen 443 default_server;
server_name name.domain.com;
ssl on;
ssl_certificate /etc/nginx/self-signed.pem;
ssl_certificate_key /etc/nginx/self-signed.pem;
ssl_protocols SSLv2 TLSv1 TLSv1.1 TLSv1.2;
ssl_client_certificate /etc/nginx/ca.cert.pem;
ssl_verify_client optional;
ssl_verify_depth 2;
ssl_session_timeout 5m;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
port_in_redirect off;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#test page for the load balancer
location /loadbalancer {
add_header X-Frame-Options "DENY";
auth_basic off;
#proxy_pass http://localhost:8080;
try_files $uri /test.html;
}
location /webapi {
add_header X-Frame-Options "DENY";
auth_basic off;
proxy_pass http://localhost:8080;
}
location/{
if ($ssl_client_verify != SUCCESS)
{
return 403;
break;
}
add_header X-Frame-Options "DENY";
proxy_pass http://localhost:8080;
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
答
可以使用proxy_set_header指令传递额外头到Tomcat。
可用变量
http://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_cipher
例
proxy_set_header SSL_DN $ssl_client_s_dn;
在你的Java应用程序,你可以阅读这个标题作进一步处理。
在旁注中,我不会保存证书中的访问级别,但会保存在服务器端数据库中,这样您可以更轻松地重新分配/更改/添加角色或撤销有效证书。
编辑 事实上nginx的支持证书撤销列表,以及: http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_crl
为nginx的+ PHP的好文章可以很容易地改编成你的使用情况:
http://nategood.com/client-side-certificate-authentication-in-ngi
这' proxy_set_header SSL_DN $ ssl_client_s_dn;'确实有效!谢谢。 – OK999
请注意,如果您需要完整证书,则有两个变量:'ssl_client_cert',其中Nginx将用制表符替换'\ n';和'ssl_client_raw_cert',它有新的行,但会破坏你的HTTP连接。 使用[官方Tomcat SSL阀](https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/SSLValve.html)不起作用(仅替换withspaces和而不是标签) – lucasvc
而对于ssl_client_cert官方的Nginx文档似乎没有提到“\ n”被替换。只提到“\ t”是前置的(但\ n实际上被替换):http://nginx.org/en/docs/http/ngx_http_ssl_module.html – Khanna111