返回> 网站首页
Tomcat与浏览器双向认证
yoours2026-02-05 20:02:17
简介一边听听音乐,一边写写文章。
一、双向认证
取代用户名密码方式登录网站管理平台,使用更安全的证书双向认证方式登录。
客户端与服务端使用ca和各自证书进行相互验证身份,验证成功后进行正常通讯交互。
二、tomcat配置
1. 配置tomcat能正常使用https访问
2. 配置server.xml文件
manage.soskp.com域名使用双向认证配置如下:
<SSLHostConfig hostName="manage.soskp.com" clientAuth="true" certificateVerification="required" SSLVerifyDepth="10" truststoreFile="c:\\ssl\\server-truststore.jks" truststorePassword="123456">
<Certificate certificateKeystoreFile="c:\\ssl\\server.jks" certificateKeystorePassword="123456" type="RSA"/>
</SSLHostConfig>
三、浏览器配置
双击证书导入到windows。
1. 将ca证书ca.crt导入到windows证书库[受信任的根证书颁发机构]。
2. 将客户端证书client.p12、client-user.p12、client-admin.p12(可以是一个或多个)导入到windows证书库[个人]。
不同客户端证书可用来区分不同管理员和不同权限。
四、浏览器访问
1. 浏览器输入需要双向认证的域名,此时浏览器会自动跳出证书选择提示框。

2. 认证成功

该信息为示例代码,认证成功后可正常访问网页或给第三方提供接口。
五、自定义证书的扩展配置
优先使用SAN用于域名验证,CN仅作后备。(SAN支持多域名,CN仅支持一个)
1. 服务端证书的SAN扩展配置:
[server_ext]
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = manage.soskp.com
DNS.2 = localhost
DNS.3 = manage.yoours.com
IP.1 = 127.0.0.1
服务端需要生成server-truststore.jks、server.jks两个tomcat使用的证书文件。
2. 客户端的SAN扩展配置:
[client_ext]
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
客户端需要生成client.p12、client-user.p12、client-admin.p12用于不同管理员和权限的证书文件。
3. 证书生成
六、使用curl测试认证
curl -v --cert client.crt --key client.key --cacert ca.crt https://manage.soskp.com/cert/info

使用第三方进行双向认证,可用于第三方应用程序进行接口调用。
七、springboot获取证书信息
编写 SecurityConfig 获取证书信息完成权限分配,部分代码如下:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, UserDetailsService userDetailsService) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/api/public/**").permitAll()
.anyRequest().authenticated())
// 添加X509认证过滤器
.addFilterBefore(new CustomX509AuthenticationFilter(userDetailsService),
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.class)
// 禁用CSRF
.csrf(AbstractHttpConfigurer::disable)
// 禁用HTTP Basic认证
.httpBasic(AbstractHttpConfigurer::disable)
// 禁用表单登录
.formLogin(AbstractHttpConfigurer::disable)
// 禁用记住我功能
.rememberMe(AbstractHttpConfigurer::disable)
.headers(headers -> headers
.httpStrictTransportSecurity(hsts -> hsts.disable())
);
return http.build();
}