此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Security 6.5.3spring-doc.cadn.net.cn

X.509 身份验证

X.509 证书身份验证最常见的用途是在使用 SSL 时验证服务器的身份,最常见的是在从浏览器使用 HTTPS 时。 浏览器会自动检查服务器提供的证书是否已由它维护的受信任证书颁发机构列表之一颁发(数字签名)。spring-doc.cadn.net.cn

您还可以将 SSL 与“相互身份验证”一起使用。然后,服务器向客户端请求有效证书,作为 SSL 握手的一部分。 服务器通过检查其证书是否由可接受的颁发机构签名来验证客户端。 如果提供了有效的证书,则可以通过应用程序中的 servlet API 获取该证书。 例如,如果您使用 Tomcat,则应阅读 Tomcat SSL 说明。 在尝试使用 Spring Security 之前,您应该先让它工作。spring-doc.cadn.net.cn

Spring Security X.509 模块使用过滤器提取证书。 它将证书映射到应用程序用户,并加载该用户授予的权限集以用于标准 Spring Security 基础架构。spring-doc.cadn.net.cn

将 X.509 身份验证添加到 Web 应用程序

响应式 X.509 身份验证类似,Servlet x509 身份验证过滤器允许从客户端提供的证书中提取身份验证Tokens。spring-doc.cadn.net.cn

以下示例显示了响应式 x509 安全配置:spring-doc.cadn.net.cn

@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
	http
		.x509(Customizer.withDefaults())
		.authorizeHttpRequests((exchanges) -> exchanges
			.anyRequest().authenticated()
		);
	return http.build();
}
@Bean
fun springSecurity(http: HttpSecurity): DefaultSecurityFilterChain? {
    http {
        authorizeHttpRequests {
            authorize(anyRequest, authenticated)
        }
        x509 { }
    }
    return http.build()
}
<http>
    <intercept-url pattern="/**" access="authenticated"/>
    <x509 />
</http>

在前面的配置中,当两者都不是principalExtractor也不authenticationManager,则使用默认值。 默认主体提取器是SubjectX500PrincipalExtractor,它从客户端提供的证书中提取 CN(公用名)字段。 默认身份验证管理器为ReactivePreAuthenticatedAuthenticationManager,它执行用户帐户验证,检查名称由principalExtractor存在,并且它未锁定、禁用或过期。spring-doc.cadn.net.cn

以下示例演示了如何覆盖这些默认值:spring-doc.cadn.net.cn

@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
	SubjectX500PrincipalExtractor principalExtractor = new SubjectX500PrincipalExtractor();
	principalExtractor.setExtractPrincipalNameFromEmail(true);


	http
		.x509((x509) -> x509
			.x509PrincipalExtractor(principalExtractor)
		)
		.authorizeHttpRequests((exchanges) -> exchanges
			.anyRequest().authenticated()
		);
	return http.build();
}
@Bean
fun springSecurity(http: HttpSecurity): DefaultSecurityFilterChain? {
    val principalExtractor = SubjectX500PrincipalExtractor()
    principalExtractor.setExtractPrincipalNameFromEmail(true)

    http {
        authorizeHttpRequests {
            authorize(anyRequest, authenticated)
        }
        x509 {
            x509PrincipalExtractor = principalExtractor
        }
    }
    return http.build()
}
<http>
    <intercept-url pattern="/**" access="authenticated"/>
    <x509 principal-extractor-ref="principalExtractor"/>
</http>
<b:bean id="principalExtractor"
    class="org.springframework.security.web.authentication.preauth.x509.SubjectX500PrincipalExtractor"
    p:extractPrincipalNameFromEmail="true"/>

在前面的示例中,用户名是从emailAddress字段而不是 CN,并且帐户查找使用自定义ReactiveAuthenticationManager实例。spring-doc.cadn.net.cn

有关配置 Netty 和WebClientcurl命令行工具,以使用双向 TLS 并启用 X.509 身份验证,请参阅 github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/x509spring-doc.cadn.net.cn

在 Tomcat 中设置 SSL

Spring Security Samples 存储库中有一些预生成的证书。 如果您不想生成自己的 SSL,可以使用这些来启用 SSL 进行测试。 这server.jks文件包含服务器证书、私有密钥和颁发机构证书。 示例应用程序中还有一些用户的客户端证书文件。 您可以在浏览器中安装这些以启用 SSL 客户端身份验证。spring-doc.cadn.net.cn

要运行支持 SSL 的 tomcat,请删除server.jks文件放入 Tomcatconf目录,并将以下连接器添加到server.xml文件:spring-doc.cadn.net.cn

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" scheme="https" secure="true"
			clientAuth="true" sslProtocol="TLS"
			keystoreFile="${catalina.home}/conf/server.jks"
			keystoreType="JKS" keystorePass="password"
			truststoreFile="${catalina.home}/conf/server.jks"
			truststoreType="JKS" truststorePass="password"
/>

clientAuth也可以设置为want如果即使客户端未提供证书,您仍然希望 SSL 连接成功。 除非您使用非 X.509 身份验证机制(例如表单身份验证),否则未提供证书的客户端无法访问受 Spring Security 保护的任何对象。spring-doc.cadn.net.cn