2015-01-12 6 views
0

스프링 보안이 통합 된 기존 애플리케이션에 CAS를 사용하여 SSO 솔루션을 구성했습니다. Stackoverflow에 대한 많은 답변을 통해 갔지만 불행히도 아무도 나를 도울 수 있습니다. 제 구성과 관련하여이 문제를 도와주십시오. 미리 감사드립니다.스프링 보안이 적용된 CAS - 리디렉션 루프

<?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:security="http://www.springframework.org/schema/security" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="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 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> 

<description>This context sets up security configurations of the core module.</description> 

<!-- Enabled support for @Secured annotations on Spring bean methods --> 
<security:global-method-security secured-annotations="enabled" 
           access-decision-manager-ref="accessDecisionManager"/> 

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

<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> 
    <property name="authenticationUserDetailsService"> 
     <bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"> 
      <constructor-arg ref="userDetailsService"/> 
     </bean> 
    </property> 
    <property name="serviceProperties" ref="serviceProperties"/> 
    <property name="ticketValidator"> 
     <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> 
      <constructor-arg index="0" value="https://localhost:8443/cas"/> 
     </bean> 
    </property> 
    <property name="key" value="an_id_for_this_auth_provider_only"/> 
</bean> 

<security:http entry-point-ref="casEntryPoint"> 
    <security:custom-filter ref="casFilter" position="CAS_FILTER"/> 
</security:http> 

<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> 
    <property name="authenticationManager" ref="authenticationManager"/> 
</bean> 

<bean id="casEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint"> 
    <property name="loginUrl" value="https://localhost:8443/cas/login"/> 
    <property name="serviceProperties" ref="serviceProperties"/> 
</bean> 

<bean id="exceptionTranslationFilter" 
     class="org.springframework.security.web.access.ExceptionTranslationFilter"> 
    <property name="authenticationEntryPoint" ref="casEntryPoint"/> 
</bean> 

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

<!-- Service that retrieves UserDetails from DB for authentication --> 
<bean id="userDetailsService" class="com.xxx.yyy.core.security.userdetails.DefaultUserDetailsService"> 
    <property name="pmUserService" ref="pmUserService"/> 
</bean> 

<bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="randomSaltSource"> 
    <property name="userPropertyToUse" value="salt"/> 
</bean> 


<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> 
    <property name="decisionVoters"> 
     <!-- At least one voter must agree that the user can access a resource --> 
     <bean class="org.springframework.security.access.vote.RoleVoter"> 
      <!-- Override the default is 'ROLE_' prefix for role names --> 
      <property name="rolePrefix"> 
       <util:constant static-field="com.xxx.yyy.core.security.SecurityConstants.AUTHORITY_PREFIX"/> 
      </property> 
     </bean> 
    </property> 
</bean> 

... 추가 보안 모듈 : 여기

내 핵심 보안 구성입니다

<?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:security="http://www.springframework.org/schema/security" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation=" 
    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 
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring- util-3.0.xsd"> 

<description>This context sets up security configurations of the web module</description> 

<import resource="web-security-urls.xml"/> 

<!-- Spring Security Filter Chain --> 
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> 
    <security:filter-chain-map path-type="ant"> 
     <security:filter-chain pattern="/**" 
           filters="securityContextPersistenceFilter, 
             logoutFilter, 
             authenticationFilter, 
             anonymousAuthenticationFilter, 
             exceptionTranslationFilter, 
             filterSecurityInterceptor"/> 
    </security:filter-chain-map> 
</bean> 

<!-- Responsible for propagation of SecurityContext on ThreadLocal from HttpSession --> 
<bean id="securityContextPersistenceFilter" 
     class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/> 

<!-- define the logout exit point --> 
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> 
    <!-- go to login page upon successful logout --> 
    <constructor-arg value="/"/> 
    <!-- Classes that get run when a user logs out --> 
    <constructor-arg> 
     <list> 
      <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> 
     </list> 
    </constructor-arg> 
    <property name="filterProcessesUrl" value="/j_spring_security_logout"/> 
</bean> 

<!-- Enable expression evaluation for Spring Security --> 
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/> 

<bean class="org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator"> 
    <constructor-arg ref="filterSecurityInterceptor"/> 
</bean> 

또한 우리는 별도의 모듈 web-security-urls.xmlo.s.s.web.access.intercept.FilterSecurityInterceptor이 보안을 선언하도록 구성되어 있습니다. URL

+0

문제가 해결되었습니다. 'filterChainProxy' bean에서'authenticationFilter'를'casFilter'로 대체해야한다고 생각합니다. – sidlejinks

답변

0

정확한 문제인지 확실하지 않지만 여기서는 필터 URL이 누락되어 무한 리디렉션 루프가 발생하는 것 같습니다.

<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> 
    <property name="authenticationManager" ref="authenticationManager"/> 
</bean> 

만 특정 URL 패턴

<property name="filterProcessesUrl" value="/j_spring_cas_security_check"/> 

나는이 문제의 동일한 유형에 갇혀 때이 내게 도움을 필터링하는 필터 URL을 추가 할 수 있습니다.

+0

피드백에 감사드립니다! 그러나 불행히도, 그것은별로 도움이되지 않았다. ( – sidlejinks

0

이 문제가 계속 발생하는지 잘 모릅니다. 나는 똑같은 얼굴을하고 있었고 신경이 쓰이고있다. CasAuthenticationFilter이 들어오는 URL (CAS 서버의 리디렉션 된 URL)에 인증이 필요한지 여부를 확인할 수없는 경우 무한 리디렉션 문제가 발생합니다.

if (!requiresAuthentication(request, response)) { 
     chain.doFilter(request, response); 

     return; 
    } 

요청이 "필터링 가능"URL로 식별되면 인증 검사가 필요합니다. "서비스 URL이"로 끝나는 경우 컨텍스트 경로와

private static final class FilterProcessUrlRequestMatcher implements RequestMatcher { 
    private final String filterProcessesUrl; 

    private FilterProcessUrlRequestMatcher(String filterProcessesUrl) { 
     Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified"); 
     Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL"); 
     this.filterProcessesUrl = filterProcessesUrl; 
    } 

    public boolean matches(HttpServletRequest request) { 
     String uri = request.getRequestURI(); 
     int pathParamIndex = uri.indexOf(';'); 

     if (pathParamIndex > 0) { 
      // strip everything after the first semi-colon 
      uri = uri.substring(0, pathParamIndex); 
     } 

     if ("".equals(request.getContextPath())) { 
      return uri.endsWith(filterProcessesUrl); 
     } 

     return uri.endsWith(request.getContextPath() + filterProcessesUrl); 
    } 
} 

는 검사가 기본적으로 확인 그래서,은 ServiceProperties 객체의 "서비스"속성에 URL이 filterProcessesUrl에 제공되는 것과 일치해야

request.getContextPath() + filterProcessesUrl . 예 :

<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties"> 
    <property name="service" 
     value="https://localhost:9444/SpringSecurity2.5/tbr/j_spring_cas_security_check" /> 
    <property name="sendRenew" value="false" /> 

</bean> 

<bean id="casFilter" 
    class="org.springframework.security.cas.web.CasAuthenticationFilter"> 
    <property name="authenticationManager" ref="authenticationManager" /> 
    <property name="authenticationSuccessHandler"> 
     <bean 
      class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler" /> 
    </property> 
    <property name="filterProcessesUrl" value="/tbr/j_spring_cas_security_check"/> 

</bean> 

참고 을위한 매칭 패턴/TBR/j_spring_cas_security_check 모두 이러한 구성에.

+0

그리고 스프링 - 보안 + CAS의 경우 서비스 URL 개념은 "일반적인"CAS 클라이언트 필터링 웹 애플 리케이션과 다르게 작동한다. 봄 보안은 요청 URL을 인증 스키마 (BASIC, FORM BASED, CAS, X.509 등)를 시도하기 전에 캐시 (세션 객체). 인증이 성공하면 캐시에서 원래 요청을 가져오고 클라이언트 리디렉션을 시도합니다 (302). 서비스 URL은 스프링 컨트롤러에서 매핑하는 URL이 아닌 CAS 필터 – user3030761

+0

의'SavedRequestAwareAuthenticationSuccessHandler (SavedRequest) session.getAttribute (SAVED_REQUEST); 문자열 targetUrl = savedRequest로 인식되는 URL입니다.getRedirectUrl(); getRedirectStrategy(). sendRedirect (요청, 응답, 대상 URL); – user3030761