CAS с Spring Security - цикл перенаправления
Я настраивал решение единого входа с использованием CAS для существующего приложения с интегрированной Spring Security. Я прошел через много ответов на Stackru, но, к сожалению, кто-нибудь мог мне помочь. Не могли бы вы помочь мне с этой проблемой с точки зрения моей конфигурации? Заранее спасибо!
Вот моя основная конфигурация безопасности:
<?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.xml
где o.s.s.web.access.intercept.FilterSecurityInterceptor
настроен для объявления безопасных URL
2 ответа
Я не уверен, что это именно та проблема, но похоже, что вам здесь не хватает URL фильтра, из-за которого вы получаете бесконечный цикл перенаправления.
<bean id="casFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
Вы можете добавить URL-адрес фильтра, чтобы фильтровать только определенный шаблон URL
<property name="filterProcessesUrl" value="/j_spring_cas_security_check"/>
Это помогло мне, когда я застрял в той же проблеме.
Я не знаю, если у вас все еще есть эта проблема. Я столкнулся с тем же, и это нервирует. Проблема бесконечных результатов перенаправления, когда CasAuthenticationFilter
не может определить, требуется ли аутентификация для входящего URL-адреса (перенаправленного URL-адреса с сервера CAS).
if (!requiresAuthentication(request, response)) {
chain.doFilter(request, response);
return;
}
Требуется проверка подлинности, если запрос идентифицирован как "фильтруемый" 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);
}
}
С контекстным путем проверка в основном проверяет, заканчивается ли "URL службы" request.getContextPath() + filterProcessesUrl
Таким образом, URL в свойстве "service" объекта ServiceProperties должен соответствовать тому, что предусмотрено в 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 в обеих этих конфигурациях.