在启用了双向X.509认证后,无论是客户端还是Java EE服务端,他们都需要相互验证各自的身份(公钥证书),在采用X.509认证期间,传递的所有数据将受到SSL/TLS传输通道的保护,从而最大限度的保证了系统的安全!
在实际应用中,X.509 CA证书大量地应用于HTTPS(TLS/SSL)中,并将它们安装到各个浏览器中。一旦浏览器接收到服务器提供的X.509 CA证书时,浏览器会根据自身维护的“trustStore”来验证证书的合法性:如果浏览器不能够自动验证它的合法身份,则交由浏览器客户手动完成。在启用双向SSL认证时,浏览器会客户还必须将自身的X.509证书提交到服务器中,此时服务器根据自身维护的“trustStore”来验证证书的合法性。
一.准备X.509证书:
前提在apps目录下创建三个目录:root server client
创建root证书:
Java代码
创建私钥 :C:\OpenSSL\apps>openssl genrsa -out root/root-key.pem 1024
- 创建证书请求 :C:\OpenSSL\apps>openssl req -new -out root/root-req.csr -key root/root-key.pem
- 自签署证书 :C:\OpenSSL\apps>openssl x509 -req -in root/root-req.csr -out root/root-cert.pem -signkey root/root-key.pem -days 3650
- 将证书导出成浏览器支持的.p12格式 :C:\OpenSSL\apps>openssl pkcs12 -export -clcerts -in root/root-cert.pem -inkey root/root-key.pem -out root/root.p12
- 打印自签证书 : C:\OpenSSL\apps>keytool -printcert -file root/root-cert.pem
创建server证书:
- 创建私钥 :C:\OpenSSL\apps>openssl genrsa -out server/server-key.pem 1024
- 创建证书请求 :C:\OpenSSL\apps>openssl req -new -out server/server-req.csr -key server/server-key.pem
- 自签署证书 :C:\OpenSSL\apps>openssl x509 -req -in server/server-req.csr -out server/server-cert.pem -signkey server/server-key.pem -CA root/root-cert.pem -CAkey root/root-key.pem -CAcreateserial -days 3650
- 将证书导出成浏览器支持的.p12格式 :C:\OpenSSL\apps>openssl pkcs12 -export -clcerts -in server/server-cert.pem -inkey server/server-key.pem -out server/server.p12
- 打印自签证书 : C:\OpenSSL\apps>keytool -printcert -file server/server-cert.pem
创建client证书:
- 创建私钥 :C:\OpenSSL\apps>openssl genrsa -out client/client-key.pem 1024
- 创建证书请求 :C:\OpenSSL\apps>openssl req -new -out client/client-req.csr -key client/client-key.pem
- 自签署证书 :C:\OpenSSL\apps>openssl x509 -req -in client/client-req.csr -out client/client-cert.pem -signkey client/client-key.pem -CA root/root-cert.pem -CAkey root/root-key.pem -CAcreateserial -days 3650
- 将证书导出成浏览器支持的.p12格式 :C:\OpenSSL\apps>openssl pkcs12 -export -clcerts -in client/client-cert.pem -inkey client/client-key.pem -out client/client.p12
- 打印自签证书 : C:\OpenSSL\apps>keytool -printcert -file client/client-cert.pem
这一步是可选的,根据root证书生成JKS文件
生成JKS文件 :
- C:\OpenSSL\apps\root>keytool -import -v -trustcacerts -storepass password -alias root -file root-cert.pem -keystore root.jks
把root.jks,root.p12,server.p12三个文件复制到C:\tomcat\conf目录去
启动tomcat SSL的配置,在server.xml中更改配置为:
- "8443" maxHttpHeaderSize="8192"
- maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
- enableLookups="false" disableUploadTimeout="true"
- acceptCount="100" scheme="https" secure="true"
- sslProtocol="TLS"
- clientAuth="true" keystoreFile="C:/tomcat/conf/server.p12"
- keystoreType="PKCS12" keystorePass="password"
- truststoreFile="C:/tomcat/conf/root.jks"
- truststoreType="JKS" truststorePass="password" />
经过以上步骤后,Tomcat服务器身份和根证书就算搞定了,但是客户身份换没有搞定。我们要把client.p12和root.p12导入到浏览器中去。
操作步骤为:打开IE->Internet选项->内容->证书
2.root.p12导入
完成以上步骤后,可以访问 了,不出意外就能看到你想要的结果
1:要想启用acegi X.509双向认证,就需要配置X509ProcessingFilter过滤器。
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"> <property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /**=channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter,x509ProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor </value> </property> </bean>
<!-- ======================== AUTHENTICATION ======================= -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> <property name="providers"> <list> <ref local="x509AuthenticationProvider"/> </list> </property> </bean> <bean id="x509ProcessingFilter" class="org.acegisecurity.ui.x509.X509ProcessingFilter"> <property name="authenticationManager"><ref local="authenticationManager"/></property> </bean>
|
2.定义X509AuthenticationProcider认证提供者
<bean id="x509AuthenticationProvider" class="org.acegisecurity.providers.x509.X509AuthenticationProvider"> <property name="x509AuthoritiesPopulator"><ref local="x509AuthoritiesPopulator"/></property> <property name="x509UserCache"><ref local="x509UserCache"/></property> </bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
<bean id="x509UserCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager"> <ref local="cacheManager"/> </property> <property name="cacheName"> <value>x509Cache</value> </property> </bean>
<bean id="x509UserCache" class="org.acegisecurity.providers.x509.cache.EhCacheBasedX509UserCache"> <property name="cache"><ref local="x509UserCacheBackend"/></property> </bean>
<bean id="x509AuthoritiesPopulator" class="org.acegisecurity.providers.x509.populator.DaoX509AuthoritiesPopulator"> <property name="userDetailsService"><ref local="jdbcDaoImpl"/></property> <!-- <property name="subjectDNRegex"><value>emailAddress=(.*?),</value></property> --> </bean>
|
3.配置EhCacheBasedX509UserCache
如上面
4.将X509ProcessingFilterEntryPoint对象提供给ExceptionTranslationFilter
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"> <property name="authenticationEntryPoint"><ref local="x509ProcessingFilterEntryPoint"/></property> </bean>
<bean id="x509ProcessingFilterEntryPoint" class="org.acegisecurity.ui.x509.X509ProcessingFilterEntryPoint"> </bean>
|
5.将X509ProcessingFilter过滤器添加到FilterChainProxy过滤器中
6.启用SSL传输通道
<bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter"> <property name="channelDecisionManager"><ref local="channelDecisionManager"/></property> <property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON \A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
\A.*\Z=REQUIRES_INSECURE_CHANNEL </value> </property> </bean>
<bean id="channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl"> <property name="channelProcessors"> <list> <ref local="secureChannelProcessor"/> <ref local="insecureChannelProcessor"/> </list> </property> </bean>
<bean id="secureChannelProcessor" class="org.acegisecurity.securechannel.SecureChannelProcessor"> </bean> <bean id="insecureChannelProcessor" class="org.acegisecurity.securechannel.InsecureChannelProcessor"> </bean>
|
解决JavaEE各容器间端口的差异性:
不同的JavaEE容器,默认时,他们服务HTTP和HTTPS请求的端口存在很大差别。比如:BEA WebLogic会采用7001(HTTP)/7002(HTTPS)组合,Tomcat(JBoss)会采用8080(HTTP)/8443(HTTPS)组合。实际生产环境中,大部分企业都会使用80/443组合。Acegi默认时,内置的X509仅仅支持80/443,8080/8443组合。可以修改:
<bean id="portResolver" class="org.acegisecurity.util.PortResolverImpl"> <property name="portMapper" ref="portMapper"></property> </bean> <bean id="portMapper" class="org.acegisecurity.util.PortMapperImpl"> <property name="portMappings"> <map> <entry key="80" value="443"/> <entry key="7001" value="7002"/> <entry key="8080" value="8443"/> <entry key="9080" value="9443"/> </map> </property> </bean>
|
<bean id="retryWithHttpsEntryPoint" class="org.acegisecurity.securechannel.RetryWithHttpsEntryPoint"> <property name="portMapper" ref="portMapper"/> <property name="portResolver" ref="portResolver"></property> </bean>
<bean id="retryWithHttpEntryPoint" class="org.acegisecurity.securechannel.RetryWithHttpEntryPoint"> <property name="portMapper" ref="portMapper"/> <property name="portResolver" ref="portResolver"></property> </bean>
|
<bean id="secureChannelProcessor" class="org.acegisecurity.securechannel.SecureChannelProcessor"> <property name="entryPoint" ref="retryWithHttpsEntryPoint" ></property> </bean>
<bean id="insecureChannelProcessor" class="org.acegisecurity.securechannel.InsecureChannelProcessor"> <property name="entryPoint" ref="retryWithHttpEntryPoint" ></property> </bean>
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"> <property name="authenticationEntryPoint"><ref local="x509ProcessingFilterEntryPoint"/></property> <property name="portResolver" ref="portResolver"></property> </bean>
|
阅读(1772) | 评论(0) | 转发(0) |