tomcat 客户端证书认证 + 指定证书用户。 如内网证书验证(某些人员才有权限)
证书生成和双向证书配置这块网上资料很多,也很详细,大家可以 百度一下
1. 证书生成
服务端证书如果公司有购买的可以直接配置(天威诚信的官网有操作说明),如果没有可以自己生成(不过浏览器每次会弹出提示)。
客户端根证书,一般如果是内网根证书为 xxx.cer 文件。 可以直接和服务端证书导入到一起:
keytool -import -v -file intranet-root-cert.crt.cer -keystore ivan.keystore -storepass mypassword
2. 双向证书配置
打开Tomcat根目录下的/conf/server.xml,找到如下配置段,修改如下:<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS" keystoreFile="d:/tomcat.keystore" keystorePass="password" truststoreFile="d:/tomcat.keystore" truststorePass="password" />Tomcat配置
打开Tomcat根目录下的/conf/server.xml,找到如下配置段(一般都被注释了,自己添加一下):
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="true" sslProtocol="TLS"
keystoreFile="d:/ivan.keystore" keystorePass="password"
truststoreFile="d:/ivan.keystore" truststorePass="password" />
简单说明下:
clientAuth:是否需要验证客户端证书。
keystoreFile:服务端证书位置,keystorePass:密码
truststoreFile:客户端根证书位置(一般和服务端证书导入到一起),truststorePass:密码
我在windows测试的时候遇到一个错误,将protocol替换一下:protocol="org.apache.coyote.http11.Http11NioProtocol"
应用配置web.xml
<!--AuthorizationsettingforSSL-->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>ClientCertUsers-onlyArea</realm-name>
<security-constraint>
<!--AuthorizationsettingforSSL-->
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
配置好了,启动Tomcat,可以测试一下,双向证书基本配置ok。
3. 高级应用
网上基本上也就是上面的情况,但是不能实现我们的用户白名单。
其实这块如果对tomcat比较熟悉的话,应该很容易处理,只是个人基本上不用tomcat,所以比较费时,这里简单整理一下,方便大家使用。
应用配置web.xml(加入角色控制)增加(如果有,修改):
<!--AuthorizationsettingforSSL-->
<security-constraint>
<!--AuthorizationsettingforSSL-->
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<web-resource-name>Admin resources</web-resource-name>
<!--这里是针对部分目录-->
<url-pattern>/interface_view.htm</url-pattern>
<url-pattern>/add_question.htm</url-pattern>
<url-pattern>/archiving.htm</url-pattern>
<url-pattern>/archiving_edit.htm</url-pattern>
<url-pattern>/view_event.htm</url-pattern>
<url-pattern>/security_event.htm</url-pattern>
<url-pattern>/report.htm</url-pattern>
<url-pattern>/month_report.htm</url-pattern>
<url-pattern>/color_handle.htm</url-pattern>
<url-pattern>/sec_tools_week_report.htm</url-pattern>
<url-pattern>/basicsetting/*</url-pattern>
<url-pattern>/setting/*</url-pattern>
</web-resource-collection>
<!--case1-->
<auth-constraint>
<description>This applies only to the "tomcat" security role</description>
<role-name>admin</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>ClientCertUsers-onlyArea</realm-name>
</login-config>
<!--case2-->
<security-role>
<role-name>admin</role-name>
</security-role>
注意一下上面的2个case。
Tomcat配置conf/tomcat-user.xml
<role rolename="manager"/>
<role rolename="admin"/>
<role rolename="user"/>
<user username="EMAILADDRESS=a@xxx.com, CN=xx, OU=Corp, O=xx, L=xx, ST=xx, C=CN" password="null" roles="admin"/>
<user username="EMAILADDRESS=b@xxx.com, CN=xx, OU=Corp, O=xx, L=xx, ST=xx, C=CN" password="null" roles="admin"/>
<user username="EMAILADDRESS=c@xxx.com, CN=xx, OU=Corp, O=xx, L=xx, ST=xx, C=CN" password="null" roles="admin"/>
使用admin的角色。
其中 <user username="EMAILADDRESS=a@xxx.com, CN=xx, OU=Corp, O=xx, L=xx, ST=xx, C=CN" password="null" roles="admin"/> 就相当于用户的白名单,我们只需要维护这个就行。
其他用户,是不能访问我们应用的指定目录的。
当然,有些人会问, <user username 肿么获取,其实就是内网证书,这里放一个jsp,想要添加的用户访问一下这个jsp就知道自己的证书信息了:
<%@ page import="java.security.cert.X509Certificate"%>
<%
//response.sendRedirect("jsp/vpay/input.jsp");
String certSubject = null;
java.security.cert.X509Certificate[] certChain=
(java.security.cert.X509Certificate[])
request.getAttribute("javax.servlet.request.X509Certificate");
if (null!=certChain){
int len=certChain.length;
if (len>0){
java.security.cert.X509Certificate cert =
(java.security.cert.X509Certificate)certChain[0];
java.security.Principal pSubject = cert.getSubjectDN();
certSubject = pSubject.getName();
}
}
%>