X.509 身份验证
X.509 证书身份验证最常见的用途是在使用 SSL 时验证服务器的身份,尤其是在浏览器中使用 HTTPS 时。浏览器会自动检查服务器提供的证书是否由其维护的可信证书颁发机构列表中的一个颁发(数字签名)。
您也可以将 SSL 与“相互身份验证”一起使用。然后,服务器作为 SSL 握手的一部分向客户端请求有效的证书。服务器通过检查客户端证书是否由可接受的机构签名来验证客户端。如果提供了有效的证书,则可以通过应用程序中的 servlet API 获取该证书。Spring Security X.509 模块通过使用过滤器来提取证书。它将证书映射到应用程序用户,并加载该用户的授权权限集,以便与标准的 Spring Security 基础设施一起使用。
您也可以将 SSL 与“相互身份验证”一起使用。然后,服务器作为 SSL 握手的一部分向客户端请求有效的证书。服务器通过检查客户端证书是否由可接受的机构签名来验证客户端。例如,如果您使用 Tomcat,则应阅读 Tomcat SSL 说明。在使用 Spring Security 尝试之前,应先确保此功能正常工作。
将 X.509 身份验证添加到 Web 应用
启用 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 客户端身份验证。
要在 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 的身份验证机制,例如表单身份验证。