第 25 章 使用X509登录

X509是一种基于双向加密的身份认证方式,它要基于SSL,并要求开启客户端证书,是一种非常强力的安全手段。

25.1. 生成证书

我们要为X509生成服务器端和客户端使用的证书。

首先生成服务端证书server.jks。

keytool -genkey -keyalg RSA -dname "cn=localhost,ou=family168,o=www.family168.com,l=china,st=beijing,c=cn" -alias server -keypass password -keystore server.jks -storepass password
        

然后生成客户端证书,并将客户端证书导入到server.jks中。

keytool -genkey -v -alias user -keyalg RSA -storetype PKCS12 -keystore user.p12 -dname "cn=user,ou=family168,o=www.family168.com,l=china,st=beijing,c=cn" -storepass password -keypass password

keytool -export -alias user -keystore user.p12 -storetype PKCS12 -storepass password -rfc -file user.cer

keytool -import -v -file user.cer -keystore server.jks -storepass password
        

最后将服务端证书导出,加入jre安全证书中。

keytool -export -trustcacerts -alias server -file server.cer -keystore server.jks -storepass password

keytool -import -trustcacerts -alias server -file server.cer -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -storepass changeit
        

25.2. 配置服务器使用双向加密

在pom.xml中对jetty进行配置,使用刚刚生成的服务端证书server.js配置SSL,并使用needClientAuth="true"启用双向加密啊。

  <connectors>
    <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
      <port>8080</port>
      <maxIdleTime>3600000</maxIdleTime>
    </connector>
    <connector implementation="org.mortbay.jetty.security.SslSocketConnector">
      <port>8443</port>
      <keystore>certificates/server.jks</keystore>
      <password>password</password>
      <keyPassword>password</keyPassword>
      <truststore>certificates/server.jks</truststore>
      <trustPassword>password</trustPassword>
      <needClientAuth>true</needClientAuth>
    </connector>
  </connectors>
  <scanIntervalSeconds>10</scanIntervalSeconds>
  <webDefaultXml>../webdefault.xml</webDefaultXml>
  <systemProperties>
    <systemProperty>
      <name>javax.net.ssl.trustStore</name>
      <value>certificates/server.jks</value>
    </systemProperty>
    <systemProperty>
      <name>javax.net.ssl.trustStorePassword</name>
      <value>password</value>
    </systemProperty>
  </systemProperties>
        

25.3. 配置X509认证

修改配置文件,添加x509配置方式

<http>
    <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" requires-channel="https"/>
    <intercept-url pattern="/**" access="ROLE_USER"  requires-channel="https"/>
    <x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>
</http>

<user-service id="userService">
    <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
    <user name="user" password="user" authorities="ROLE_USER" />
</user-service>
        

x509中,subject-principal-regex会从客户端证书中获取用户名,将CN部分当做username来使用,因为服务器端会绝对相信客户端证书中的信息,所以不会再去使用userService中的密码对用户进行校验,一旦证书校验通过,直接对用户进行授权。

现在系统已经配置好了x509认证方式,只要将生成的客户端证书user.p12导入到浏览器中,直接访问系统就会发现已经用user用户登录到系统中了。

如果使用IE浏览器,可以直接双击user.p12进行导入。

如果使用FireFox浏览器,需要点击浏览器工具条上的“工具”->“选项”->“高级”->“查看证书”,在“证书管理器”中导入user.p12。

实例在ch115。