X.509认证
18.1. 概述
X.509证书认证最常见的使用方法是使用SSL验证服务器的身份,通常情况是在浏览器使用SSL。 浏览器使用一个它维护的可信任的证书权限列表,自动检测服务器发出的证书(比如数字签名)。
你也可以使用SSL进行“mutual authentication”相互认证;服务器会从客户端请求一个合法的证书,作为SSL握手协议的一部分。 服务器将验证客户端,通过检测它被签在一个可接受的权限里的认证。 如果已经提供了一个有效的证书,就可以从程序的servlet API里获得。 Spring Security X.509模块确认证书,使用过滤器,传递一个配置好的X.509认证提供器,允许任何复杂的特定程序检测使用。 它也可以为应用程序的用户映射证书,并使用标准的Spring Security基础设施读取用户的已授予权限集合。
你应该很熟悉使用证书,在使用Spring Security之前为你的servlet容器启动客户端认证。 大多数工作都是创建和安装合适的证书和密匙。 比如,如果你使用tomcat,可以阅读这里的教程http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html。 在你把它用在Spring Security里之前,先知道它是怎么工作,是很重要的。
18.2. 把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。如果你的application context里只定义了一个bean,就不需要使用它。
subject-principal-regex应该包含一个单独的组。 比如默认的表达式"CN=(.*?),"匹配普通的名字字段。 所以,如果证书主题名是"CN=Jimi Hendrix, OU=...",就会得到一个名叫"Jimi Hendrix"的用户。 这个匹配是大小写不敏感的。 所以"emailAddress=(.?),"也会匹配"
[email protected],CN=...",得到一个"
[email protected]"用户名。 如果客户端给出一个证书,并成功获得了一个合法用户名,然后在安全环境里应该有一个有效的Authentication对象。 如果没有找到证书,或没有找到对应的用户,安全环境会保持为空。 这说明你可以很简单的和其他选项一起使用X.509认证,比如基于表单登录。
18.3. 为tomcat配置SSL
在Spring Security项目的samples/certificate目录下,有几个已经生成好的证书。 如果你不想自己去生成,就可以使用们启用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"
/>
clientAuth 也可以设置成 want,如果你希望客户端没有提供证书的时候SSL链接也能成功。 客户端不提供证书的话,就不能访问Spring Security的任何安全对象,除非你使用了非X.509认证机制,比如表单认证。