【问题标题】:Spring Security and CAS IntegrationSpring Security 和 CAS 集成
【发布时间】:2012-04-07 17:57:09
【问题描述】:

任何人都可以在此处粘贴简单的步骤来集成 Spring 安全性和 CAS 以进行单点登录和单点注销。 注意我不想要任何基于角色的访问。我有一个已经与 Spring Security 集成的 Web 应用程序。现在我尝试使用 CAS 执行 SSO,但我收到此错误 sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

这是我当前的 spring security.xml

       <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/security 
        http://www.springframework.org/schema/security/spring-security-3.1.xsd
        ">

<sec:http entry-point-ref="casProcessingFilterEntryPoint" >
        <sec:intercept-url pattern="/**" access="ROLE_USER" />
        <sec:logout logout-success-url="/loggedout.jsp" invalidate-session="true"/>
        <sec:custom-filter ref="casAuthenticationFilter" after="CAS_FILTER"/>
    </sec:http>

    <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider ref="casAuthenticationProvider"/>
    </sec:authentication-manager>

<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationFailureHandler">
            <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
                <property name="defaultFailureUrl" value="/casfailed.jsp"/>
            </bean>
        </property>
        <property name="authenticationSuccessHandler">
            <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
                <property name="defaultTargetUrl" value="/"/>
            </bean>
        </property>
    </bean>

    <bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
        <property name="loginUrl" value="https://cegicollabdev.india.xxx.com:8443/cas/login"/>
        <property name="serviceProperties" ref="serviceProperties"/>
    </bean>

    <bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
        <property name="userDetailsService" ref="userService"/>
        <property name="serviceProperties" ref="serviceProperties" />
        <property name="ticketValidator">
            <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
                <constructor-arg index="0" value="https://cegicollabdev.india.tcs.com:8443/cas" />
                </bean>
        </property>
        <property name="key" value="an_id_for_this_auth_provider_only"/>
    </bean>


    <bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
        <property name="service" value="http://localhost:8080/dbcomparision/j_spring_cas_security_check"/>
        <property name="sendRenew" value="false"/>
    </bean>

    <bean id="userService" class="com.tcs.ceg.services.impl.UserServiceImpl" />

 <!--     <sec:global-method-security pre-post-annotations="enabled" />

    <sec:http pattern="/css/**" security="none"/>
    <sec:http pattern="/images/**" security="none"/>
    <sec:http pattern="/js/**" security="none"/>
    <sec:http pattern="/index.jsp" security="none"/>
    <sec:http pattern="/app/addNewUser.json" security="none"/>
    <sec:http pattern="/dbcomplogin.jsp" security="none"/>
    <sec:http pattern="/loggedout.jsp" security="none"/>

    <sec:http use-expressions="true">-->
        <!--
             Allow all other requests. In a real application you should
             adopt a whitelisting approach where access is not allowed by default
          -->
      <!--    <sec:intercept-url pattern="/**" access="isAuthenticated()" />
        <sec:form-login login-page='/dbcomplogin.jsp'
          authentication-failure-url="/dbcomplogin.jsp?login_error=1"
          default-target-url="/index.jsp" />
        <sec:logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"/>
        <sec:remember-me />

    </sec:http>

    <bean id="myUserService" class="com.tcs.ceg.services.impl.UserServiceImpl" />
    <sec:authentication-manager>
    <sec:authentication-provider user-service-ref="myUserService" />
    </sec:authentication-manager> -->

</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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>Spring3MVC</display-name>
  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-rootcontext.xml
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>
      <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>
    <!--
      - Loads the root application context of this web app at startup.
    -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/app/*</url-pattern>
  </servlet-mapping>
 <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>
    <listener>
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
    </listener>

</web-app>

这是我的 Spring-rootcontext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" >
  <context:annotation-config />
 <mvc:annotation-driven />
    <context:component-scan
        base-package="com.tcs.ceg" />

 <jee:jndi-lookup id="dataSource1" jndi-name="jdbc/PmdDS"/>


    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource1" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="current_session_context_class">thread</prop>
                <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
                <prop key="hibernate.connection.release_mode">auto</prop>
            </props>
        </property>
    </bean>



    <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    </beans>

这是我的 spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" >



    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass">
        <value>
            org.springframework.web.servlet.view.tiles2.TilesView
        </value>
    </property>
    </bean>
    <bean id="tilesConfigurer"
    class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/tiles.xml</value>
        </list>
    </property>
</bean>
<bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="classpath:messages" />
    <property name="defaultEncoding" value="UTF-8"/>
</bean>

<bean id="localeChangeInterceptor"
    class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
    <property name="paramName" value="lang" />
</bean>

<bean id="localeResolver"
    class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="defaultLocale" value="en"/>
</bean>

<bean id="handlerMapping"
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
        <ref bean="localeChangeInterceptor" />
    </property>
</bean>



    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- one of the properties available; the maximum file size in bytes -->
        <property name="maxUploadSize" value="1000000000000"/>
    </bean>
</beans>

问题:1 sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

问题 2:未调用自定义 UserServiceimpl

问题 3:这是正确的吗? &lt;property name="service" value="http://localhost:8080/dbcomparision/j_spring_cas_security_check"/&gt; ,注意在我的程序中,j_spring_cas_security_check 没有请求映射

【问题讨论】:

    标签: java spring-security cas


    【解决方案1】:

    让 CAS 身份验证工作的最简单步骤是从 Spring Security 源代码树构建并运行 CAS sample

    在尝试使用 CAS 或将其与您的应用程序集成之前,您确实需要了解 CAS 的工作原理。我将从 CAS 文档和描述 interactions between CAS and Spring Security 的 Spring Security 参考手册开始。

    j_spring_cas_security_check 是 CAS 对用户进行身份验证后在您的应用程序中重定向到的 URL(请参阅上面的链接)。

    即使您的应用程序没有对用户进行身份验证,它通常仍然具有它所知道的用户概念。它还必须为这些用户加载角色,这是 CAS 不处理的,因此是 user-service 声明。密码不会被使用。

    上面的文档解释了您的应用程序如何验证登录是否成功。它基本上调用 CAS 服务器,传入服务票证并用用户名返回响应。

    【讨论】:

    • 我已经编辑了问题?再次遇到问题,无法解决..请帮助
    • 现在收到此错误..知道如何解决吗?原因是:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider。 certpath.SunCertPathBuilderException: 无法在 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) 处找到请求目标的有效证书路径
    【解决方案2】:

    解决问题

    sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求目标的有效证书路径

    我们按照 3 个步骤指示我们的应用服务器的 JDK 接受 cas 服务器的证书(在您的项目中,它是 cegicollabdev.india.tcs.com:8443)

    1. 下载InstallCert.java,复制到JDK'bin文件夹

      http://code.google.com/p/java-use-examples/source/browse/trunk/src/com/aw/ad/util/InstallCert.java

    2. 以管理员权限打开命令行工具(如果您使用的是 Window 7/Vista)。切换到 JDK 的 bin 文件夹并构建这个 java 文件

      javac InstallCert.java

    3. 安装cas服务器证书

      java InstallCert cegicollabdev.india.tcs.com:8443

      出现提示时点击 1。

    就是这样。

    【讨论】:

      【解决方案3】:

      无论如何,单点登录已经完成..花了很多时间来弄清楚,但相信我,如果你有一个想要做的思想设置,那么无论如何你都会成功..这是解决方案.. 这是我更新的 spring-security.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:sec="http://www.springframework.org/schema/security"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:aop="http://www.springframework.org/schema/aop"
          xmlns:context="http://www.springframework.org/schema/context"
          xsi:schemaLocation="
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
              http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
              http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
              http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
              http://www.springframework.org/schema/mvc
              http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
              http://www.springframework.org/schema/beans 
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/security 
              http://www.springframework.org/schema/security/spring-security-3.1.xsd
              ">
      
      <sec:http entry-point-ref="casProcessingFilterEntryPoint" >
              <sec:intercept-url pattern="/**" access="ROLE_ADMIN" />
              <sec:logout logout-success-url="https://abc.com:8443/cas/logout" delete-cookies="JSESSIONID"/>
              <sec:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
          <sec:custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
              <sec:custom-filter ref="casAuthenticationFilter" after="CAS_FILTER"/>
          </sec:http>
      
          <sec:authentication-manager alias="authenticationManager">
              <sec:authentication-provider ref="casAuthenticationProvider"/>
          </sec:authentication-manager>
      
      <bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
              <property name="authenticationManager" ref="authenticationManager"/>
              <property name="authenticationFailureHandler">
                  <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
                      <property name="defaultFailureUrl" value="/casfailed.jsp"/>
                  </bean>
              </property>
              <property name="authenticationSuccessHandler">
                  <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
                      <property name="defaultTargetUrl" value="/"/>
                  </bean>
              </property>
              <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
              <property name="proxyReceptorUrl" value="/secure/receptor" />
          </bean>
      
          <bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
              <property name="loginUrl" value="https://abc.com:8443/cas/login"/>
              <property name="serviceProperties" ref="serviceProperties"/>
          </bean>
      
          <bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
              <property name="userDetailsService" ref="userService"/>
              <property name="serviceProperties" ref="serviceProperties" />
              <property name="ticketValidator">
                  <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
                      <constructor-arg index="0" value="https://abc.com:8443/cas" />
                      <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
                      <property name="proxyCallbackUrl" value="http://localhost:8080/dbcomparision/secure/receptor" />
      
                      </bean>
              </property>
              <property name="key" value="an_id_for_this_auth_provider_only"/>
          </bean>
      
         <bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />
          <bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
              <property name="service" value="http://localhost:8080/dbcomparision/j_spring_cas_security_check"/>
              <property name="sendRenew" value="false"/>
          </bean>
      
          <bean id="userService" class="com.tcs.ceg.services.impl.UserServiceImpl" />
          <!-- This filter handles a Single Logout Request from the CAS Server -->
        <bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
        <!-- This filter redirects to the CAS Server to signal Single Logout should be performed -->
        <bean id="requestSingleLogoutFilter"
              class="org.springframework.security.web.authentication.logout.LogoutFilter">
          <constructor-arg value="https://abc.com:8443/cas/logout"/>
          <constructor-arg>
            <bean class=
                "org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
          </constructor-arg>
          <property name="filterProcessesUrl" value="/j_spring_cas_security_logout"/>
        </bean>
      
      </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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>Spring3MVC</display-name>
        <context-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>
                  /WEB-INF/spring-rootcontext.xml
                  /WEB-INF/spring-security.xml
              </param-value>
          </context-param>
            <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>
          <!--
            - Loads the root application context of this web app at startup.
          -->
          <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
      
      
        <welcome-file-list>
          <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
      
        <servlet>
          <servlet-name>spring</servlet-name>
          <servlet-class>
                  org.springframework.web.servlet.DispatcherServlet
              </servlet-class>
          <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
          <servlet-name>spring</servlet-name>
          <url-pattern>/app/*</url-pattern>
        </servlet-mapping>
       <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>
          <listener>
              <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
          </listener>
      
      </web-app>
      

      我通过将 CAS 服务器的“cacerts”文件从 CAS 服务器的 java\jre\lib\security 复制到我的本地 java\jre\lib\security 来解决此异常 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),并且异常被抽出。

      【讨论】:

      • 你能发布你的 UserServiceImpl 代码吗?这对我会有很大帮助。
      猜你喜欢
      • 2012-12-02
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 2013-05-25
      • 1970-01-01
      • 2015-12-28
      相关资源
      最近更新 更多