X.509 认证

本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

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

你也可以使用 “mutual authentication” (双向认证) 的SSL。然后服务器向客户端请求一个有效的证书作为SSL握手的一部分。服务器通过检查客户端的证书是否由可接受的权威机构签署来验证其身份。如果提供了有效的证书,可以通过应用程序中的servlet API获得。Spring Security X.509 模块通过使用一个过滤器提取证书。它将证书映射到应用程序用户,并加载该用户的授权机构集,以便与标准的Spring安全基础设施一起使用。

例如,如果你使用Tomcat,你应该阅读 Tomcat的SSL说明。在使用Spring Security之前,你应该先把这个工作做好。

将 X.509 认证添加到你的web应用中

启用 X.509 客户端认证是非常简单的。要做到这一点,在你的http security 命名空间配置中添加 <x509/> 元素。

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

该元素有两个可选的属性。

  • subject-principal-regex:用来从证书的主题名称中提取用户名的正则表达式。默认值显示在前面的列表中。这是传递给 UserDetailsService 的用户名,用于加载用户的授权。

  • user-service-ref:这是 UserDetailsService 的Bean ID,将用于X.509。如果在你的 application context 中只有一个定义,就不需要它了。

subject-principal-regex 应该包含一个组。例如,默认表达式(CN=(.*?))与通用名称字段匹配。因此,如果证书中的主体名称是 "CN=Jimi Hendrix, OU=…​",这就给出了一个用户名 "Jimi Hendrix"。匹配是不区分大小写的。因此,"emailAddress=(.*?)," 匹配 "EMAILADDRESS=jimi@hendrix.org,CN=…​",给出一个用户名 "jimi@hendrix.org"。如果客户端出示了一个证书,并且成功提取了一个有效的用户名,那么在 security context 中应该有一个有效的 Authentication 对象。如果没有找到证书或找不到相应的用户, security context 文仍然是空的。这意味着你可以使用X.509认证与其他选项,如基于表单的登录。

在Tomcat中设置SSL

Spring Security Samples repository 中有一些预先生成的证书。如果你不想生成自己的证书,你可以使用这些证书来启用SSL进行测试。server.jks 文件包含服务器证书、私钥和签发机构证书。还有一些客户证书文件,是为样本应用程序的用户准备的。你可以在浏览器中安装这些文件以启用SSL客户端认证。

要运行支持SSL的tomcat,将 server.jks 文件放入 tomcat conf 目录,并在 server.xml 文件中添加以下 connector。

<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 保障的对象。