My webapp using Spring, and I want to config it with CAS to SSO but can not run. I running with JBOSS AS 7.1.
My Webapp using Spring and spring security version 3.1.4
CAS 4.0.2
In CAS server, I login with LDAP success, but went redirect to my app has an error:
Caused by: 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 sun.security.ssl.Alerts.getSSLException(Alerts.java:192) [jsse.jar:1.7.0_79]
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1904) [jsse.jar:1.7.0_79]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279) [jsse.jar:1.7.0_79]
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:273) [jsse.jar:1.7.0_79]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1446) [jsse.jar:1.7.0_79]
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:209) [jsse.jar:1.7.0_79]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:901) [jsse.jar:1.7.0_79]
at sun.security.ssl.Handshaker.process_record(Handshaker.java:837) [jsse.jar:1.7.0_79]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1023) [jsse.jar:1.7.0_79]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332) [jsse.jar:1.7.0_79]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359) [jsse.jar:1.7.0_79]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343) [jsse.jar:1.7.0_79]
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563) [rt.jar:1.7.0_79]
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) [rt.jar:1.7.0_79]
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1092) [rt.jar:1.7.0_79]
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250) [rt.jar:1.7.0_79]
at org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:191) [cas-client-core-3.1.12.jar:]
... 32 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) [rt.jar:1.7.0_79]
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) [rt.jar:1.7.0_79]
at sun.security.validator.Validator.validate(Validator.java:260) [rt.jar:1.7.0_79]
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) [jsse.jar:1.7.0_79]
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) [jsse.jar:1.7.0_79]
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126) [jsse.jar:1.7.0_79]
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1428) [jsse.jar:1.7.0_79]
... 44 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) [rt.jar:1.7.0_79]
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) [rt.jar:1.7.0_79]
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) [rt.jar:1.7.0_79]
... 50 more
This is my config:
1. Config spring security
spring-security-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- <http entry-point-ref="casProcessingFilterEntryPoint" access-denied-page="/denied.jsp">
<intercept-url pattern="/secure/extreme/**" access="ROLE_ADMINISTRATORS"
requires-channel="https"/> <intercept-url pattern="/secure/**" access="ROLE_NORMALUSERS"/>
<logout logout-success-url="/cas-logout.jsp"/> <custom-filter ref="casAuthenticationFilter"
after="CAS_FILTER"/> </http> -->
<http pattern="/static/**" security="none" />
<http entry-point-ref="casProcessingFilterEntryPoint" auto-config="true"
use-expressions="true">
<form-login login-page="/login" login-processing-url="/j_spring_security_check"
authentication-failure-url="/login?error=true"
authentication-failure-handler-ref="loginFailureHandler"
authentication-success-handler-ref="loginSuccessHandler"
default-target-url="/home" always-use-default-target="false" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/accessDenied"
access="hasRole('ROLE_GUEST') or isAuthenticated()" />
<intercept-url pattern="/system/**" access="hasAnyRole('R01')" />
<intercept-url pattern="/system/**" access="hasRole('R01')" />
<intercept-url pattern="/**" access="hasRole('ROLE_AUTHED')" />
<access-denied-handler error-page="/accessDenied" />
<logout logout-success-url="/" />
<custom-filter ref="casAuthenticationFilter" after="CAS_FILTER" />
</http>
<beans:bean id="loginSuccessHandler"
class="vn.com.bank.vcapital.security.LoginSuccessHandler">
<beans:property name="useReferer" value="true" />
</beans:bean>
<beans:bean id="loginFailureHandler"
class="vn.com.bank.vcapital.security.LoginFailureHandler">
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="casAuthenticationProvider" />
</authentication-manager>
<beans:bean id="casAuthenticationFilter"
class="org.springframework.security.cas.web.CasAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureHandler">
<beans:bean
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/accessDenied" />
</beans:bean>
</beans:property>
<beans:property name="authenticationSuccessHandler">
<beans:bean
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/" />
</beans:bean>
</beans:property>
<beans:property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
<beans:property name="proxyReceptorUrl" value="/secure/receptor" />
</beans:bean>
<beans:bean id="casProcessingFilterEntryPoint"
class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<beans:property name="loginUrl" value="https://localhost:9443/cas/login" />
<beans:property name="serviceProperties" ref="serviceProperties" />
</beans:bean>
<beans:bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider"
p:key="my_password_for_this_auth_provider_only"
p:serviceProperties-ref="serviceProperties"
p:authenticationUserDetailsService-ref="userDetailsService">
<beans:property name="ticketValidator">
<beans:bean class="org.jasig.cas.client.validation.Saml11TicketValidator">
<beans:constructor-arg index="0"
value="https://localhost:9443/cas" />
</beans:bean>
</beans:property>
</beans:bean>
<beans:bean id="proxyGrantingTicketStorage"
class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />
<beans:bean id="serviceProperties"
class="org.springframework.security.cas.ServiceProperties">
<beans:property name="service"
value="https://localhost:9443/vcapital/j_spring_cas_security_check" />
<beans:property name="sendRenew" value="false" />
</beans:bean>
<beans:bean id="userDetailsService"
class="org.springframework.security.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService">
<beans:constructor-arg>
<beans:list>
<beans:value>authorities</beans:value>
</beans:list>
</beans:constructor-arg>
</beans:bean>
</beans:beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>vcapital</display-name>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServletContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--
- Loads the root application context of this web app at startup.
- The application context is then available via
- WebApplicationContextUtils.getWebApplicationContext(servletContext).
-->
<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
</web-app>
Config JBOSS AS
standalone.xml
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
<configuration>
<jsp-configuration development="true"/>
</configuration>
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" redirect-port="9443"/>
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
<ssl name="jboss" key-alias="jboss" password="123456" certificate-key-file="C:/Java/jdk1.7.0_79/jre/lib/security/vccb" certificate-file="C:/Java/jdk1.7.0_79/jre/lib/security/vccb"/>
</connector>
<virtual-server name="default-host" enable-welcome-root="true">
<alias name="localhost"/>
<alias name="example.com"/>
</virtual-server>
</subsystem>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="management-native" interface="management" port="${jboss.management.native.port:9999}"/>
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9443}"/>
<socket-binding name="ajp" port="8009"/>
<socket-binding name="http" port="8080"/>
<socket-binding name="https" port="9443"/>
<socket-binding name="osgi-http" interface="management" port="8090"/>
<socket-binding name="remoting" port="4447"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="localhost" port="25"/>
</outbound-socket-binding>
</socket-binding-group>
Step to create certificate
C:\Java\jdk1.7.0_79\bin>keytool -genkey -alias jboss -keystore ..\jre\lib\security\vccb -storepass 123456 -keypass 123456 -dname "CN=localhost,OU=VCCB,O=VCCB,L=HCM,C=VN"
C:\Java\jdk1.7.0_79\bin>keytool -keystore ../jre/lib/security/vccb -export -alias jboss -file server.crt
Enter keystore password:
Certificate stored in file <server.crt>
C:\Java\jdk1.7.0_79\bin>keytool -import -file server.crt -keystore ../jre/lib/security/vccb
Enter keystore password:
Certificate already exists in keystore under alias <jboss>
Do you still want to add it? [no]: yes
Certificate was added to keystore
I know why it can not run.
When we created the certificate, we must import it into the JDK (JDK using with Jboss AS. With me is jdk1.7.0_17\jre\lib\security\cacerts)
http://help.adobe.com/en_US/livecycle/9.0/adminHelp/admin.htm?content=000217.html http://www.thegeekstuff.com/2014/03/install-jboss-ssl/