33. X.509 身份验证

33.1 Overview

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

您还可以将 SSL 与“相互身份验证”结合使用;然后,服务器将作为 SSL 握手的一部分从 Client 端请求有效的证书。服务器将通过检查其证书是否由可接受的授权机构签名来对 Client 端进行身份验证。如果提供了有效证书,则可以通过应用程序中的 Servlet API 获得该证书。 Spring Security X.509 模块使用过滤器提取证书。它将证书 Map 到应用程序用户,并加载该用户的授权权限集以与标准 Spring Security 基础结构一起使用。

在尝试将其与 Spring Security 结合使用之前,您应该熟悉使用证书并为 Servlet 容器设置 Client 端身份验证。大多数工作是在创建和安装合适的证书和密钥。例如,如果您使用的是 Tomcat,请阅读http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html的说明。在使用 Spring Security 进行尝试之前,一定要先做好这项工作,这一点很重要

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

启用 X.509Client 端身份验证非常简单。只需将<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]”。如果 Client 端出示证书并且成功提取了有效的用户名,则安全上下文中应该有一个有效的Authentication对象。如果找不到证书,或者找不到相应的用户,则安全上下文将保持为空。这意味着您可以轻松地将 X.509 身份验证与其他选项(例如基于表单的登录名)一起使用。

33.3 在 Tomcat 中设置 SSL

Spring Security 项目的samples/certificate目录中有一些预先生成的证书。如果您不想生成自己的 SSL,则可以使用它们来启用 SSL 进行测试。文件server.jks包含服务器证书,私钥和颁发证书颁发机构的证书。示例应用程序中还为用户提供了一些 Client 端证书文件。您可以将这些安装在浏览器中以启用 SSLClient 端身份验证。

要运行具有 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"
/>

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