X.509 身份验证

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

您也可以使用带有“双向认证”的 SSL。在这种情况下,服务器会在 SSL 握手过程中向客户端请求有效的证书。服务器通过检查证书是否由可接受的机构签署来验证客户端。如果提供了有效的证书,则可以在应用程序中通过 servlet API 获取它。Spring Security X.509 模块使用过滤器提取证书。它将证书映射到应用程序用户,并加载该用户的授权集,以便与标准 Spring Security 基础设施一起使用。

您也可以使用带有“双向认证”的 SSL。在这种情况下,服务器会在 SSL 握手过程中向客户端请求有效的证书。服务器通过检查证书是否由可接受的机构签署来验证客户端。例如,如果您使用 Tomcat,您应该阅读 Tomcat SSL 指南。您应该先让它正常工作,然后再尝试使用 Spring Security。

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

启用 X.509 客户端认证非常简单。为此,请将 <x509/> 元素添加到您的 http 安全命名空间配置中。

<http>
...
	<x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>;
</http>

该元素有两个可选属性。

  • subject-principal-regex。用于从证书的主题名称中提取用户名正则表达式。默认值如前所述。这是传递给 UserDetailsService 用于加载用户授权的用户名。

  • user-service-ref。这是要与 X.509 一起使用的 UserDetailsService 的 bean ID。如果您的应用程序上下文中只定义了一个,则不需要它。

subject-principal-regex 应该包含一个单独的组。例如,默认表达式 (CN=(.*?)) 匹配通用名称字段。因此,如果证书中的主体名称为“CN=Jimi Hendrix, OU=…​”,则会得到用户名“Jimi Hendrix”。匹配项不区分大小写。因此,“emailAddress=(.*?),” 匹配“EMAILADDRESS=[email protected],CN=…​”,得到用户名 "[email protected]"。如果客户端提供证书并且成功提取了有效的用户名,则安全上下文中应该有一个有效的 Authentication 对象。如果找不到证书或找不到相应的用户,则安全上下文将保持为空。这意味着您可以将 X.509 身份验证与其他选项一起使用,例如基于表单的登录。

在 Tomcat 中设置 SSL

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

要使用 SSL 支持运行 tomcat,请将 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。除非您使用非 X.509 身份验证机制(例如表单身份验证),否则没有提供证书的客户端无法访问 Spring Security 保护的任何对象。