spring-projects / spring-projects/spring-security
Redirection not happening to original request after proxy ticket validation
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
I am using CAS proxy tickets in my applications, the proxy ticket receiving application (from which I am expecting resource) validates the proxy ticket and never goes back to original target url.
After successful validation of proxy ticket in CASAuthenticationProvider, AbstractAuthenticationProcessingFilter.successfulAuthentication is not called due to final implementation of successfulAuthentication() in CASAuthenticationFilter
from CASAuthenticationFilter.successfulAuthentication()
boolean continueFilterChain = proxyTicketRequest(
serviceTicketRequest(request, response), request);
if (!continueFilterChain) {
super.successfulAuthentication(request, response, chain, authResult);
return;
}
In above code, after proxy ticket validation, continueFilterChain is always true and super.successfulAuthentication(request, response, chain, authResult); never gets executed and never invokes , SavedRequestAwareAuthenticationSuccessHandler to goto target url.
I am thinking it is a bug, please correct me if I am wrong.
Following is my spring configuration.
`@Bean
public SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler() {
SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler = new
SimpleUrlAuthenticationFailureHandler();
return simpleUrlAuthenticationFailureHandler;
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler() {
SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
savedRequestAwareAuthenticationSuccessHandler.setDefaultTargetUrl("/");
return savedRequestAwareAuthenticationSuccessHandler;
}
@Bean
public ServiceProperties serviceProperties() {
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService(serviceUrl);
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
}
@Bean
public Cas20ProxyTicketValidator cas20ProxyTicketValidator() {
Cas20ProxyTicketValidator validator = new Cas20ProxyTicketValidator(validationUrl);
validator.setProxyGrantingTicketStorage(proxyGrantingTicketStorage());
validator.setAcceptAnyProxy(true);
return validator;
}
@Bean
public SecurityContextLogoutHandler securityContextLogoutHandler() {
SecurityContextLogoutHandler securityContextLogoutHandler = new SecurityContextLogoutHandler();
return securityContextLogoutHandler;
}
@Bean
@DependsOn("securityContextLogoutHandler")
public LogoutFilter requestSingleLogoutFilter() {
LogoutFilter requestSingleLogoutFilter = new LogoutFilter(logoutUrl, securityContextLogoutHandler());
requestSingleLogoutFilter.setFilterProcessesUrl("/j_spring_cas_security_logout");
return requestSingleLogoutFilter;
}
@Bean
public SingleSignOutFilter singleLogoutFilter() {
SingleSignOutFilter singleLogoutFilter = new SingleSignOutFilter();
return singleLogoutFilter;
}
@Bean
public ProxyGrantingTicketStorage proxyGrantingTicketStorage() {
ProxyGrantingTicketStorage proxyGrantingTicketStorage = new ProxyGrantingTicketStorageImpl();
return proxyGrantingTicketStorage;
}
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
casAuthenticationFilter.setProxyGrantingTicketStorage(proxyGrantingTicketStorage());
casAuthenticationFilter.setProxyReceptorUrl("/j_spring_cas_security_proxyreceptor");
casAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
casAuthenticationFilter.setServiceProperties(serviceProperties());
casAuthenticationFilter.setAuthenticationDetailsSource(dynamicServiceResolver());
casAuthenticationFilter.setAuthenticationSuccessHandler(savedRequestAwareAuthenticationSuccessHandler());
casAuthenticationFilter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler());
return casAuthenticationFilter;
}
@Bean
AuthenticationDetailsSource<HttpServletRequest, ServiceAuthenticationDetails> dynamicServiceResolver() {
return new AuthenticationDetailsSource<HttpServletRequest, ServiceAuthenticationDetails>() {
public ServiceAuthenticationDetails buildDetails(HttpServletRequest context) {
final String url = makeDynamicUrlFromRequest(context);
return new ServiceAuthenticationDetails() {
public String getServiceUrl() {
return url;
}
};
}
};
}
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint() {
@Override
protected String createServiceUrl(final HttpServletRequest request, final HttpServletResponse response) {
return CommonUtils.constructServiceUrl(request, response, null, casServer,
serviceProperties().getArtifactParameter(), false);
}
};
casAuthenticationEntryPoint.setLoginUrl(loginUrl);
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
casAuthenticationProvider.setAuthenticationUserDetailsService(authenticationUserDetailsService());
casAuthenticationProvider.setServiceProperties(serviceProperties());
casAuthenticationProvider.setTicketValidator(cas20ProxyTicketValidator());
casAuthenticationProvider.setKey("test");
return casAuthenticationProvider;
}
@Bean(name = "authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(casAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().addFilter(casAuthenticationFilter())
.addFilterBefore(requestSingleLogoutFilter(), LogoutFilter.class)
.addFilterBefore(singleLogoutFilter(), CasAuthenticationFilter.class).authorizeRequests().anyRequest()
.authenticated().and().formLogin().usernameParameter("j_username").passwordParameter("j_password").and()
.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint());
http.headers().contentTypeOptions().xssProtection().cacheControl().frameOptions()
.addHeaderWriter(new HstsHeaderWriter(60 * 60, false));
}
@Bean
public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> authenticationUserDetailsService() {
return new CasUserPrincipalService();
}
private String makeDynamicUrlFromRequest(HttpServletRequest request) {
return casServer + request.getRequestURI();
}`
Version
Spring security 3.2.4
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with CASAuthenticationFilter.successfulAuthentication() and compare its proxy-ticket path with AbstractAuthenticationProcessingFilter.successfulAuthentication(). Trace the continueFilterChain decision and the configured SavedRequestAwareAuthenticationSuccessHandler. Done means a successfully validated proxy ticket returns to the original saved request, with regression coverage for this path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- authentication, backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100