使用Spring Security + CAS获得循环重定向,但应该正常工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Spring Security + CAS获得循环重定向,但应该正常工作相关的知识,希望对你有一定的参考价值。

我正在尝试将基本应用程序从仅使用Spring Security更改为使用CAS,以启用SSO。但是我正在某个地方获得重定向循环,我无法找出问题所在。我已经做了两个其他模拟应用程序,并且CAS没有问题,因为它们正在工作。我使用Java配置代替XML,取自here。我已经尝试了XML配置的例子,但我仍然得到相同的结果。我的猜测是对于authenticationManager的问题,它无法从Spring Security中检测到用户。该日志至少表示一个AnonymousUser并抛出AccessDeniedException。但它适用于其他两个具有相似配置的模拟应用程序(我甚至尝试过复制它,但错误仍然存​​在)。我一直试图解决这个问题几天没有成功,所以任何帮助都表示赞赏。我在Windows 8上使用Tomcat 8,Spring 4.2和Ja-sig CAS 4.0.0。

我的WebSecurityConfig:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DataSource dataSource;

    @Autowired
    @Resource(name="CASuserDetailsService")
    private AuthenticationUserDetailsService userDetailsService;

    @Bean
    public ServiceProperties serviceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService("https://localhost:8443/i9t-YM/j_spring_cas_security_check");
        serviceProperties.setSendRenew(false);
        return serviceProperties;
    }

    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
        casAuthenticationProvider.setAuthenticationUserDetailsService(authenticationUserDetailsService());
        casAuthenticationProvider.setServiceProperties(serviceProperties());
        casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
        casAuthenticationProvider.setKey("some_id_for_this_cas_prov");
        return casAuthenticationProvider;
    }

    @Bean
    public AuthenticationUserDetailsService authenticationUserDetailsService() {
        return userDetailsService;
    }

    @Bean
    public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
        return new Cas20ServiceTicketValidator("https://localhost:8443/cas");
    }

    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        casAuthenticationFilter.setAuthenticationManager(authenticationManager());
        casAuthenticationFilter.setFilterProcessesUrl("https://localhost:8443/i9t-YM/j_spring_cas_security_check");
        return casAuthenticationFilter;
    }

    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
        CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
        casAuthenticationEntryPoint.setLoginUrl("https://localhost:8443/cas/login");
        casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
        return casAuthenticationEntryPoint;
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(casAuthenticationProvider());
        //Yes, joe is with a md5 poassword on the database, but i'm using it here as a mockup to see if it works. Also, if there's no ".password", it'll throw an ConstructorCantBeNull or something like that.
        auth.inMemoryAuthentication().withUser("joe").password("joe").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilter(casAuthenticationFilter());
        http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint());
        http.authorizeRequests().antMatchers("/**").access("hasRole('ROLE_USER')");
//      http.authorizeRequests().antMatchers("/resource", "/secure/**").access("hasRole('ROLE_USER')");
//      http.authorizeRequests().antMatchers("/resources/**").permitAll();
//      http.httpBasic().and().authorizeRequests().antMatchers("/index.html", "/home.html", "/login.html", "/")
//              .permitAll().anyRequest().authenticated()
//              //.and().addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
//              //.csrf().csrfTokenRepository(csrfTokenRepository())
//              ;
    }

    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }

}

TestCasAuthenticationUserDetailsS​​ervice(请注意我已尝试通过多种方式使其工作......)

@Service("CASuserDetailsService")
public class TestCasAuthenticationUserDetailsService implements AuthenticationUserDetailsService, UserDetailsService {
    @Autowired
    private DataSource dataSource;


    @Override
    public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException {
        List<GrantedAuthority> authorities = new ArrayList<>();
        System.out.println(token.getName());
        System.out.println(token.toString());
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        return new User(token.getName(), token.getName(), authorities);
    }


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<GrantedAuthority> authorities = new ArrayList<>();
        System.out.println(username);
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        return new User(username, username, authorities);
    }
}

我的web.xml:

<servlet>
        <servlet-name>springServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring-context.xml
<!--                /WEB-INF/spring-security.xml  -->
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/erro.html</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/404.html</location>
    </error-page>

    <!-- CAS -->
    <filter>
        <filter-name>CAS-SSO-Filter</filter-name>
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CAS-SSO-Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
    </listener>

    <!-- Force SSL -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>i9t-YM</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

来自模拟应用程序的applicationContext-security.xml:

<security:http auto-config="true" entry-point-ref="casEntryPoint">
        <security:intercept-url pattern="/*" access="ROLE_USER" />
        <security:custom-filter position="CAS_FILTER"
            ref="casFilter" />
    </security:http>

    <security:user-service id="userService">
        <security:user name="joe" authorities="ROLE_USER" />
    </security:user-service>

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

    <bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
        <property name="service"
            value="https://localhost:8443/casTest/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" />
    </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="casAuthenticationProvider"
        class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
        <property name="authenticationUserDetailsService">
            <bean
                class=" org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <constructor-arg ref="userService" />
            </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" />
<!--                <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" /> -->
<!--                <property name="proxyCallbackUrl" value="https://localhost:8443/cas/secure/receptor" /> -->
            </bean>
        </property>
        <property name="key" value="some_id_for_this_cas_prov" />
    </bean>

    <bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />

SSL也适用于他们。有循环时记录的错误:

    2015-08-27 11:29:59,026 INFO [org.jasig.cas.CentralAuthenticationServiceImpl] - <Granted service ticket [ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org] for service [https://localhost:8443/i9t-YM/j_spring_cas_security_check] for user [joe]>
2015-08-27 11:29:59,027 INFO [com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: joe
WHAT: ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org for https://localhost:8443/i9t-YM/j_spring_cas_security_check
ACTION: SERVICE_TICKET_CREATED
APPLICATION: CAS
WHEN: Thu Aug 27 11:29:59 BRT 2015
CLIENT IP ADDRESS: 0:0:0:0:0:0:0:1
SERVER IP ADDRESS: 0:0:0:0:0:0:0:1
=============================================================

>
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
HttpSession returned null object for SPRING_SECURITY_CONTEXT
No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@1c993da0. A new one will be created.
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
Request 'GET /j_spring_cas_security_check' doesn't match 'POST /logout
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 6 of 12 in additional filter chain; firing Filter: 'CasAuthenticationFilter'
Checking match of request : '/j_spring_cas_security_check'; against 'https://localhost:8443/i9t-ym/j_spring_cas_security_check'
serviceTicketRequest = false
proxyReceptorConfigured = false
proxyReceptorRequest = false
proxyTicketRequest = false
requiresAuthentication = false
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
pathInfo: both null (property equals)
queryString: arg1=ticket=ST-9-DElbuW6RP24GocThfiBt-cas01.example.org; arg2=ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org (property not equals)
saved request doesn't match
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 0CA64FA23DD44EECC261887599F2541B; Granted Authorities: ROLE_ANONYMOUS'
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
Request '/j_spring_cas_security_check' matched by universal pattern '/**'
Secure object: FilterInvocation: URL: /j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org; Attributes: [hasRole('ROLE_USER')]
Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 0CA64FA23DD44EECC261887599F2541B; Granted Authorities: ROLE_ANONYMOUS
Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2c4d2096, returned: -1
Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:232)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:123)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:614)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1527)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1484)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Trying to match using Ant [pattern='/**', GET]
Request '/j_spring_cas_security_check' matched by universal pattern '/**'
Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']]
Checking match of request : '/j_spring_cas_security_check'; against '/**/favicon.ico'
matches = true
Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@37c9ddce, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]]
httpRequestMediaTypes=[text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8]
Processing text/html
application/json .isCompatibleWith text/html = false
Processing application/xhtml+xml
application/json .isCompatibleWith application/xhtml+xml = false
Processing application/xml;q=0.9
application/json .isCompatibleWith application/xml;q=0.9 = false
Processing */*;q=0.8
Ignoring
Did not match any media types
matches = true
Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
matches = true
All requestMatchers returned true
DefaultSavedRequest added to Session: DefaultSavedRequest[https://localhost:8443/i9t-YM/j_spring_cas_security_check?ticket=ST-10-yA1U32bOGJ6Gg5HShohm-cas01.example.org]
Calling Authentication entry point.
SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
SecurityContextHolder now cleared, as request processing completed

我在这里尝试过其他问题的一些解决方案,但我不知道如果我只是做一些我看不到的傻事,或者我搞砸了配置。任何遗漏,只要告诉我,我会补充。提前致谢!

编辑:它不是从应用程序验证票证,但它应该工作。另一个应用程序按预期工作:

2015-08-28 08:44:39,049 INFO [org.jasig.cas.CentralAuthenticationServiceImpl] - <Granted service ticket [ST-44-QmOXrKwachmUcM16DqV4-cas01.example.org] for service [https://localhost:8443/casTest/j_spring_cas_security_check] for user [joe]>
2015-08-28 08:44:39,049 INFO [com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: joe
WHAT: ST-44-QmOXrKwachmUcM16DqV4-cas01.example.org for https://localhost:8443/casTest/j_spring_cas_security_check
ACTION: SERVICE_TICKET_CREATED
APPLICATION: CAS
WHEN: Fri Aug 28 08:44:39 BRT 2015
CLIENT IP ADDRESS: 0:0:0:0:0:0:0:1
SERVER IP ADDRESS: 0:0:0:0:0:0:0:1
=============================================================

>
2015-08-28 08:44:39,063 INFO [com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: audit:unknown
WHAT: ST-44-QmOXrKwachmUcM16DqV4-cas01.example.org
ACTION: SERVICE_TICKET_VALIDATED
APPLICATION: CAS
WHEN: Fri Aug 28 08:44:39 BRT 2015
CLIENT IP ADDRESS: 127.0.0.1
SERVER IP ADDRESS: 127.0.0.1
=============================================================
>

EDIT2:一个非常奇怪的补充:其他示例应用程序单独使用servlet,并且正在使用spring 3.2。现在,我试图模仿原始版本复制到此示例,并尝试降级它直到它工作。问题是我不能让它工作任何@Controller注释或类似...但重定向消失了。如果我更新我的maven,并从4.2到3.2,循环就消失了。但是,如果我在4.2上,除了版本之外什么也没有改变,那就是循环!

答案

从Spring Security 4.x开始,CAS的端点从/j_spring_cas_security_check变为/login/cas(参见https://stackoverflow.com/a/35136587/3585320

另一答案

pom.hml

<spring.version>4.3.2.RELEASE</spring.version>
<spring.security.version>4.1.3.RELEASE</spring.security.version>

弹簧security.xml文件

<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
    <!-- spring security 3.x -->
    <!--
    <property name="service" value="http://localhost:8080/j_spring_cas_security_check"/>
    -->
    <property name="service" value="http://localhost:8080/login/cas"/>
    <property name="sendRenew" value="false"/>
</bean>

参考:

Migrating from Spring Security 3.x to 4.x (XML Configuration)

Migrating from Spring Security 3.x to 4.x (Java Configuration)

CasAuthenticationFilter filterProcessesUrl属性的默认值从“/ j_spring_cas_security_check”更改为“/ login / cas”。这意味着如果未显式指定filterProcessesUrl属性,则需要更新配置。例如,如果使用Spring Security 3.2.x的应用程序包含类似于以下内容的配置:

CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);

在Spring Security 4.x中,需要将配置更新为类似于以下内容的内容:

xml配置:

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

java配置:

CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setFilterProcessesUrl("/j_spring_cas_security_check");
filter.setAuthenticationManager(authenticationManager);

或者,可以更新ServiceProperties以使用新的默认值:

xml配置:

<bean id="serviceProperties"
        class="org.springframework.security.cas.ServiceProperties">
    <property name="service"
            value="https://example.com/cas-sample/login/cas"/>
</bean>

java配置:

ServiceProperties properties = new ServiceProperties();
properties.setService("https://example.com/cas-sample/login/cas");
另一答案

CAS服务器已将服务票证(ticket参数)返回到j_spring_cas_security_check URL。它应该工作。在org.jasig.cas包上启用DEBUG日志以了解CAS客户端中发生的情况:服务票证验证是否成功?

另一答案
serviceProperties.setAuthenticateAllArtifacts(true);
另一答案

因此,它的“答案”只是将Spring Security从4.0.2降级到3.2.8。然后我只需要通过注释spring-security-xml再次从XML模板更改为Java配置:

<param-value>
                /WEB-INF/spring-context.xml
<!--                /WEB-INF/spring-security.xml  -->
</param-value>

不确定这是否是“实际”答案,因为我不知道是否有一个特定的Spring Security 4配置使其工作与3.2不同,但是因为我使用4.2的所有Spring功能只是春天,他们不需要降级工作。

以上是关于使用Spring Security + CAS获得循环重定向,但应该正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 整合Cas

使用 Spring Security 和 CAS 单点注销

Grails Spring Security 和 CAS 问题

spring security+cas(cas proxy配置)

Spring Security - CAS 自定义到 LDAP 集成

Spring-security-cas 插件单点注销不起作用