X.509 认证

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

您也可以使用“相互认证”的 SSL。服务器随后在 SSL 握手期间向客户端请求一个有效证书。服务器通过检查客户端证书是否由可接受的机构签名来认证客户端。如果提供了有效证书,则可以通过应用程序中的 servlet API 获取。例如,如果您使用 Tomcat,您应该阅读 Tomcat SSL 说明。在尝试与 Spring Security 配合使用之前,您应该先使其正常工作。

Spring Security X.509 模块通过使用过滤器提取证书。它将证书映射到应用程序用户,并加载该用户的授权集,以便与标准 Spring Security 基础设施一起使用,特别是当使用 HttpSecurity DSL 时,至少包括 FACTOR_X509 授权。

向您的 Web 应用程序添加 X.509 认证

响应式 X.509 认证类似,servlet x509 认证过滤器允许从客户端提供的证书中提取认证令牌。

以下示例展示了响应式 x509 安全配置

  • Java

  • Kotlin

  • Xml

@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>

在上述配置中,当未提供 principalExtractorauthenticationManager 时,将使用默认值。默认的主体提取器是 SubjectX500PrincipalExtractor,它从客户端提供的证书中提取 CN(通用名称)字段。默认的认证管理器是 ReactivePreAuthenticatedAuthenticationManager,它执行用户账户验证,检查是否存在由 principalExtractor 提取的名称的用户账户,并且该账户未被锁定、禁用或过期。

以下示例演示了如何覆盖这些默认值

  • Java

  • Kotlin

  • Xml

@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 实例。

有关配置 Netty 和 WebClientcurl 命令行工具以使用相互 TLS 并启用 X.509 认证的示例,请参阅 github.com/spring-projects/spring-security-samples/tree/main/servlet/java-configuration/authentication/x509

在 Tomcat 中设置 SSL

Spring Security 示例仓库中有一些预先生成的证书。如果您不想生成自己的证书,可以使用它们来启用 SSL 进行测试。server.jks 文件包含服务器证书、私钥和颁发机构证书。还有一些客户端证书文件,用于示例应用程序中的用户。您可以将这些证书安装到浏览器中以启用 SSL 客户端认证。

要在 Tomcat 中运行 SSL 支持,请将 server.jks 文件放入 Tomcat 的 conf 目录,并在 server.xml 文件中添加以下连接器

<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"
/>

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

© . This site is unofficial and not affiliated with VMware.