有时候我们可能需要限定特定的用户进行访问,且用户需要使用数字证书进行访问,这也就是所谓的客户端证书认证。
其实做客户端认证并不是很难,首先你需要一个CA证书,一般情况下你可以使用一个自签名的证书用作CA证书,然后通过这个CA证书给别人的证书请求文件进行签名,然后客户端可以将自己的证书和私钥转成PFX格式的证书进行安装。下面还是主要介绍下服务器端实现的原理吧。
那么一个WEB应用如果需要开启客户端证书认证的话,就需要添加一些配置。
这里以Apache和Java举例。
Listen 8443
<VirtualHost _default_:8443>
JkMountCopy On
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile conf_ext/server.crt
SSLCertificateKeyFile conf_ext/server.key
SSLCACertificateFile conf_ext/intranet-ca.cer
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
SSLVerifyClient require
SSLVerifyDepth 10
SSLOptions +StdEnvVars
RequestHeader unset SSL_CLIENT_S_DN_Email
RequestHeader add SSL_CLIENT_S_DN_Email %{SSL_CLIENT_S_DN_Email}e
</VirtualHost>
这里是配置,将SSLVerifyClient设为require,并设置好CA证书,
这里除了使用ssl_mod外还使用了headers_mod这个模块,主要是为了将证书中的email添加到http的请求的头中。
RequestHeader unset SSL_CLIENT_S_DN_Email
这句主要是为了防止客户端自己将Email设置到http header中,所以这里做了一次清除工作之后再将认证通过的客户端证书通过
RequestHeader add SSL_CLIENT_S_DN_Email %{SSL_CLIENT_S_DN_Email}e
将dn的email设置进去。
之后比如Apache将请求转发给Jboss之类的Servlet容器后,
我们可以通过Java代码获得这个email。
String email = ((HttpServletRequest)request).getHeader("SSL_CLIENT_S_DN_Email");
至于之后你通过这个信息去做用户的认证以及登录就很简单了。