在 Tomcat 中,还可以通过客户端数字证书来确认用户的身份。注意,只有当你的 Web 应用在使用 SSL(即 HTTPS)协议时,才能够使用 CLIENT-CERT 客户端证书验证方式。
当 web.xml 文件中的 <auth-method> 元素设置为 CLIENT-CERT 时,表明应用使用的是客户端证书验证。
CLIENT-CERT 验证允许客户端认证不用密码,而是浏览器提供客户端 X.509 数字证书作为登录认证。每一个用户会得到 Web 应用能够辨认识别的唯一数字证书。
用户在得到数字证书后,可以将数字证书导入到浏览器中,由浏览器来管理。当用户访问 Web 应用时,浏览器自动将证书提供给服务器。
(1)生成服务端证书,如下:
C:UsersAdministratorDesktop>keytool -genkey -alias server -keypass 123456 -keyalg RSA -keysize 1024 -keystore server.keystore -validity 365 -storepass 123456 您的名字与姓氏是什么? [Unknown]: www.hxstrive.com 您的组织单位名称是什么? [Unknown]: hxstrive 您的组织名称是什么? [Unknown]: hxstrive 您所在的城市或区域名称是什么? [Unknown]: CD 您所在的省/市/自治区名称是什么? [Unknown]: SC 该单位的双字母国家/地区代码是什么? [Unknown]: CN CN=www.hxstrive.com, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN是否正确? [否]: Y
(2)生成客户端证书,采用 PKCS12 格式。如下:
C:UsersAdministratorDesktop>keytool -genkey -alias client -keyalg RSA -storetype PKCS12 -keystore client.p12 -keypass 123456 -storepass 123456 您的名字与姓氏是什么? [Unknown]: client 您的组织单位名称是什么? [Unknown]: hxstrive 您的组织名称是什么? [Unknown]: hxstrive 您所在的城市或区域名称是什么? [Unknown]: CD 您所在的省/市/自治区名称是什么? [Unknown]: SC 该单位的双字母国家/地区代码是什么? [Unknown]: CN CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN是否正确? [否]: Y
注意:
PKCS#12是一种交换数字证书的加密标准,用来描述个人身份信息。如:用户公钥、私钥、证书等。
在密码学中,PKCS #12定义了一种存档文件格式,用于实现存储许多加密对象在一个单独的文件中。通常用它来打包一个私钥及有关的 X.509 证书,或者打包信任链的全部项目。
用户可以双击 P12 后缀的证书文件,打开证书导入向导,将证书导入到当前系统。
(3)将上面生成的 P12 客户端证书导出为一个单独的 CER 文件,如下:
C:UsersAdministratorDesktop>keytool -export -alias client -keystore client.p12 -storetype PKCS12 -storepass 123456 -keypass 123456 -file client.cer 存储在文件 <client.cer> 中的证书
(4)将上面导出的单独的客户端证书 CER 文件导入到服务器的证书库,且添加为一个信任证书。如下:
C:UsersAdministratorDesktop>keytool -import -v -file client.cer -keystore server.keystore -storepass 123456 所有者: CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN 发布者: CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN 序列号: 2dd005e8 有效期开始日期: Mon Jun 27 13:28:39 CST 2022, 截止日期: Sun Sep 25 13:28:39 CST 2022 证书指纹: MD5: B4:06:77:E4:3A:10:0B:0A:87:6B:86:D3:68:77:D0:DD SHA1: D5:1D:93:9E:CE:D7:9E:F8:B5:4C:80:63:88:3C:FA:CB:0F:47:30:C9 SHA256: 2C:09:F1:C1:4A:53:1B:19:AE:E8:8E:5B:61:CF:D4:04:E0:F5:34:E3:73:EB:50:6E:4F:38:37:2F:2D:7B:EF:F9 签名算法名称: SHA256withRSA 版本: 3 扩展: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 6A 09 42 FB CB 98 78 E6 6B 67 30 C4 7B A5 B9 D8 j.B...x.kg0..... 0010: B2 41 8D 3C .A.< ] ] 是否信任此证书? [否]: y 证书已添加到密钥库中 [正在存储server.keystore]
(5)查看我们的服务器证书库,确定客户端证书是否导入成功。如下:
C:UsersAdministratorDesktop>keytool -list -keystore server.keystore 输入密钥库口令: 密钥库类型: JKS 密钥库提供方: SUN 您的密钥库包含 2 个条目 server, 2022-6-27, PrivateKeyEntry, 证书指纹 (SHA1): DC:E9:4C:97:FE:EF:57:32:64:6A:CE:11:EA:66:34:CC:34:B1:C3:F9 mykey, 2022-6-27, trustedCertEntry, 证书指纹 (SHA1): D5:1D:93:9E:CE:D7:9E:F8:B5:4C:80:63:88:3C:FA:CB:0F:47:30:C9
编辑 %CATALINA_HOME%/conf/server.xml 配置文件,添加 HTTPS 配置信息,如下:
<?xml version='1.0' encoding='utf-8'?> <Server port="8005" shutdown="SHUTDOWN"> <!-- ... --> <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS" keystoreFile="D:/apache-tomcat-7.0.64-2/conf/cert/server.keystore" keystorePass="123456" truststoreFile="D:/apache-tomcat-7.0.64-2/conf/cert/server.keystore" truststorePass="123456" /> <!-- ... --> </Server>
上面配置中,keystoreFile 一般保存的是我们的私钥,用来加解密或者为别人做签名。truststoreFile 中保存的是一些可信任的证书,主要是 java 在代码中访问某个 https 的时候对被访问者进行认证的,以确保其实可信任的。
注意:如果要开启双向认证一定要将 clientAuth 设置为 true。
双击我们生成的 client.p12 文件,打开证书导入向导,如下图,选择默认的“当前用户”,点击下一步:
直接点击下一步:
输入生成证书密钥库的密码(即生成证书的第二步,生成客户端证书输入的密钥库密码),然后继续点击下一步:
选择默认的“根据证书类型,自动选择证书存储”项,继续点击“下一步”:
点击“完成”按钮完成证书的导入:
这里我们为了方便依然使用 tomcat 自带的 UserDatabase 领域配置,该领域将使用 tomcat-users.xml 下面配置的用户信息。配置如下:
<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <role rolename="admin-gui"/> <user username="CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN" password="null" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui"/> </tomcat-users>
由于我们采用证书验证用户身份,因此设置 password 密码为 null。但是要注意 username 的设置,必须设置成生成客户端证书时录入的证书信息,这里是“CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN”。
小技巧:
如果你不知道怎样填写 username 中的值,那么你先直接访问 Web 程序,此时 Web 程序肯定不能访问。我们可以连续多刷新几次,由于 tomcat 的领域外面配置了 LockOutRealm,会提示你正在进行暴力破解,且会给出你正确的 username 信息。如下:
<Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm>Tomcat 警告输出如下:
信息: Starting ProtocolHandler ["ajp-bio-8009"] 六月 27, 2022 11:36:38 下午 org.apache.catalina.startup.Catalina start 信息: Server startup in 1866 ms 六月 27, 2022 11:36:53 下午 org.apache.catalina.realm.LockOutRealm authenticate 警告: An attempt was made to authenticate the locked user "CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN" 六月 27, 2022 11:36:53 下午 org.apache.catalina.realm.LockOutRealm authenticate 警告: An attempt was made to authenticate the locked user "CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN" 六月 27, 2022 11:36:54 下午 org.apache.catalina.realm.LockOutRealm authenticate 警告: An attempt was made to authenticate the locked user "CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN" ...直接将“CN=client, OU=hxstrive, O=hxstrive, L=CD, ST=SC, C=CN”拷贝过去用就是。
到这里,我们已经完成 tomcat 配置和客户端证书的导入,接下来启动 tomcat。在浏览器中输入 https://localhost:8443 地址,浏览器提示选择证书,这里我们选择我们自签名的 client 证书,如下图:
然后,就可以正常访问我们的 Web 应用了。如下图: