How to config webapp using Spring security SSO with cas and running on Jboss 7.1?

716 views Asked by At

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
1

There are 1 answers

0
Nguyen Ha On

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/