2015-10-05 2 views
1

У меня есть веб-приложение Tomcat 8, оно выполняется на порту 8080 на сервере. Любой входящий запрос на порт 443 перенаправляется на localhost: 8080, используя Nginx для обслуживания веб-приложения.Проверка подлинности клиента TLS с веб-приложением Nginx и Tomcat

Я пытаюсь настроить взаимную аутентификацию &, затем проанализировать клиентский сертификат, который был использован для аутентификации приложением. Эта информация затем будет использована приложением для определения того, должен ли пользователь иметь права admin или user. Сертификат клиента будет содержать строку admin или user в поле Common Name (CN).

Я могу достичь взаимной аутентификации & ниже - это текущий nginx ssl.conf Но проблема в том, что информация сертификата не передается веб-приложению tomcat для анализа данных. Есть ли способ, доступный в 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; 
    } 
} 

ответ

1

Вы можете использовать proxy_set_header директиву передать дополнительные заголовки к вашему коту.

Доступные переменные

http://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_cipher

Пример

proxy_set_header SSL_DN $ssl_client_s_dn; 

В вашем Java приложение, которое вы можете прочитать эти заголовки для дальнейшей обработки.

На стороне примечания Я бы не сохранил уровень доступа в сертификате, а в базе данных на стороне сервера, таким образом вы могли бы переназначить/изменить/добавить роли проще или отозвать действительный сертификат.

EDIT На самом деле 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

+0

Это ' proxy_set_header SSL_DN $ ssl_client_s_dn; 'действительно работал! Спасибо. – OK999

+1

Обратите внимание, что если вы хотите получить полный сертификат, есть две переменные: 'ssl_client_cert', где Nginx заменит' \ n' вкладками; и 'ssl_client_raw_cert', который имеет новые строки, но нарушает ваше HTTP-соединение. Использование [официального клапана SSL Tomcat] (https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/valves/SSLValve.html) не работает (заменяется только пробелами и не вкладки) – lucasvc

+0

И официальный Nginx-документ для ssl_client_cert, похоже, не упоминает, что «\ n» заменены. Только упоминание «\ t» добавляется (но \ n фактически заменяется): http://nginx.org/en/docs/http/ngx_http_ssl_module.html – Khanna111

Смежные вопросы