CAS-https解决PKIX path building failed的问题(new)

CAS默认走https协议,需要配置名证书

安装证书

一、首先要在浏览器打开需要证书的网站,然后把证书下载下来,保存的证书名称随意命名,只要保证唯一性(这个唯一性下文有解释)

二、然后把证书复制到%JAVA_HOME%/jre/bin/路径下,即保证证书与keytool.exe文件同目录(其实不同也行,但是执行命令时需要指定路径)

三、导入过程如下:

复制完成之后打开doc窗口:运行-cmd

keytool -import -v -trustcacerts -alias taobao -file taobao.cer -storepass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts

解释说明:

1、taobao 是可以自己修改的名称,  taobao.cer 是导出的证书,同样,这里的证书名字也是随便取的,但前提是保证将C:\Program Files\Java\jdk1.6.0_24\jre\lib\security目录的cacerts文件内之前没有导入同名证书,就是要保证你将要导入的证书名称唯一性。

2、changeit 是密码, java默认的。

3、keytool是jdk中bin目录的一个exe文件,是jdk默认自带的,在我电脑的目录是:C:\Program Files\Java\jdk1.6.0_24\jre\bin\keytool.exe

4、%JAVA_HOME%/jre/lib/security/cacerts 这个路径中%JAVA_HOME%/jre/lib/security/是路径,cacerts是文件(即将要把证书导入到其中的文件)。当然要确保你已经配置过java_home环境变量,我的java_home环境变量为:C:\Program Files\Java\jdk1.6.0_24

5、其他保持不变。

6、如果提示:"是否信任此证书? [否]:"  ,那么请输入"y"。

当出现:”证书已添加到密钥库中 [正在存储cacerts]“的时候,那么恭喜你已经添加成功。

注意:如果提示找不到指定文件,那么有可能是路径错了,我这里是先执行cd C:\Program Files\Java\jdk1.6.0_24\jre\bin\ 来到keytool文所在目录执行以上命令。

以后更新时,先删除原来的证书,然后导入新的证书 。  

下面是一些常用命令:

//查看cacerts中的证书列表:

              keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"  -storepass changeit

//删除cacerts中指定名称的证书:

              keytool -delete -alias taobao -keystore "%JAVA_HOME%/jre/lib/security/cacerts"  -storepass changeit

//导入指定证书到cacerts:
              keytool -import -alias taobao -file taobao.cer -keystore "%JAVA_HOME%/jre/lib/security/cacerts"  -storepass changeit-trustcacerts


但是安装了证书之后访问,CAS跳转会报如下错误:

PKIX path building failed的问题 


[ERROR] http-8080-Processor25 2010-01-20 15:29:28,640 org.jasig.cas.client.validation.Cas20ServiceTicketValidator     - javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
	at org.jasig.cas.client.validation.AbstractCasProtocolUrlBasedTicketValidator.retrieveResponseFromServer(AbstractCasProtocolUrlBasedTicketValidator.java:58)
	at org.jasig.cas.client.validation.AbstractUrlBasedTicketValidator.validate(AbstractUrlBasedTicketValidator.java:167)
	at org.jasig.cas.client.validation.AbstractTicketValidationFilter.doFilter(AbstractTicketValidationFilter.java:141)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:137)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
	at org.jasig.cas.client.authentication.AuthenticationFilter.doFilter(AuthenticationFilter.java:149)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
	at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:78)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
	at com.web114.web.filter.UTF8EncoderFilter.doFilter(UTF8EncoderFilter.java:57)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
	at java.lang.Thread.run(Unknown Source)

更改源码,屏蔽问题

定位错误代码的源码:

protected final String retrieveResponseFromServer(final URL validationUrl,
			final String ticket) {
		HttpURLConnection connection = null;
		try {
			connection = (HttpURLConnection) validationUrl.openConnection();
			final BufferedReader in = new BufferedReader(new InputStreamReader(
					connection.getInputStream()));

			String line;
			final StringBuffer stringBuffer = new StringBuffer(255);

			synchronized (stringBuffer) {
				while ((line = in.readLine()) != null) {
					stringBuffer.append(line);
					stringBuffer.append("\n");
				}
				return stringBuffer.toString();
			}

		} catch (final IOException e) {
			log.error(e, e);
			return null;
		} catch (final Exception e1){
			log.error(e1, e1);
			return null;
		}finally {
			if (connection != null) {
				connection.disconnect();
			}
		}
	}

说是证书出问题了,服务器不信任我们自己创建的证书,所以在代码中必须要忽略证书信任问题。只要在创建connection之前调用两个方法:

trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
具体的实现是:
HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            System.out.println("Warning: URL Host: " + urlHostName + " vs. "
                               + session.getPeerHost());
            return true;
        }
    };
	
	private static void trustAllHttpsCertificates() throws Exception {
		javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
		javax.net.ssl.TrustManager tm = new miTM();
		trustAllCerts[0] = tm;
		javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
				.getInstance("SSL");
		sc.init(null, trustAllCerts, null);
		javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
				.getSocketFactory());
	}

	static class miTM implements javax.net.ssl.TrustManager,
			javax.net.ssl.X509TrustManager {
		public java.security.cert.X509Certificate[] getAcceptedIssuers() {
			return null;
		}

		public boolean isServerTrusted(
				java.security.cert.X509Certificate[] certs) {
			return true;
		}

		public boolean isClientTrusted(
				java.security.cert.X509Certificate[] certs) {
			return true;
		}

		public void checkServerTrusted(
				java.security.cert.X509Certificate[] certs, String authType)
				throws java.security.cert.CertificateException {
			return;
		}

		public void checkClientTrusted(
				java.security.cert.X509Certificate[] certs, String authType)
				throws java.security.cert.CertificateException {
			return;
		}
	}

下面附上改后源码:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值