Open srinivasthalapalli opened 7 years ago
This also happens to me with, and I am NOT using proxy validation at all. I have traced it down to the same decision point:
boolean continueFilterChain = proxyTicketRequest(
serviceTicketRequest(request, response), request);
if (!continueFilterChain) {
super.successfulAuthentication(request, response, chain, authResult);
return;
The continueFilterChain
is always true, so super.succesfulAuthentication
never gets called and the associated SavedRequestAwareAuthenticationSuccessHandler
never redirects to the originally requested URL.
In my situation, I left proxy config off (as I dont want my app to support proxy configuration):
package org.mitre.facilitysafety.reportviewer.configuration;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.validation.Cas30ProxyTicketValidator;
import org.mitre.facilitysafety.reportviewer.auth.CasUserDetailsService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
/**
* CAS configuration based upon the sample XML configuration from the spring
* security project.
*
* @see <a href=
* "https://github.com/spring-projects/spring-security/blob/4.2.3.RELEASE/samples/xml/cas/cassample/src/main/webapp/WEB-INF/applicationContext-security.xml">XML
* configuration</a>
*/
@Configuration
@ComponentScan( basePackages = {
"org.mitre.facilitysafety.reportviewer.configuration" } )
public class CasConfiguration {
/** This services URL base (ex: https://app.example.com/foo) **/
@Value( "${cas.service}" )
@Qualifier( "casService" )
private String casService;
/** The CAS server URL base (ex: https://sso.example.com/cas) **/
@Value( "${cas.server}" )
@Qualifier( "casServer" )
private String casServer;
@Bean
public CasAuthenticationProvider casAuthenticationProvider(
ServiceProperties casServiceProperties ) {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setKey( "casAuthProviderKey" );
provider.setServiceProperties( casServiceProperties );
provider.setAuthenticationUserDetailsService( new CasUserDetailsService() );
provider.setTicketValidator( new Cas30ProxyTicketValidator( casServer ) );
return provider;
}
/**
* Returns the CAS entry point (ie: entry-point-ref).
*
* @param serviceProperties
* The service properties
* @return The CAS entry point
*
* @see <a href=
* "https://github.com/spring-projects/spring-security/blob/4.2.3.RELEASE/samples/xml/cas/cassample/src/main/webapp/WEB-INF/applicationContext-security.xml#L55-L57">casEntryPoint</a>
* @see <a href="https://stackoverflow.com/a/24691937/516433">How to set
* entry-point-ref with java config</a>
* @see <a href=
* "https://spring.io/guides/tutorials/spring-boot-oauth2">Example of
* setting entry-point-ref with java config</a>
*/
@Bean
public CasAuthenticationEntryPoint casEntryPoint(
ServiceProperties casServiceProperties ) {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setServiceProperties( casServiceProperties );
entryPoint.setLoginUrl( casServer + "/login" );
return entryPoint;
}
/**
* This CAS authentication filter. Need authenticaitonManager, but it
* <em>MUST</em> be <code>@Lazy</code> or it will result in a circular
* reference when autowiring into the SecurityConfiguration.
*
* @return A CAS authentication filter
* @see <a href=
* "https://github.com/spring-projects/spring-security/blob/4.2.3.RELEASE/samples/xml/cas/cassample/src/main/webapp/WEB-INF/applicationContext-security.xml#L58-L73">requestSingleLogoutFilter</a>
*/
@Bean
public CasAuthenticationFilter casFilter( ServiceProperties casServiceProperties,
@Lazy AuthenticationManager authenticationManager ) {
CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setAuthenticationManager( authenticationManager );
filter.setServiceProperties( casServiceProperties );
filter.setAuthenticationDetailsSource( new ServiceAuthenticationDetailsSource( casServiceProperties ) );
return filter;
}
/**
* This filter redirects to the CAS Server to signal Single Logout should be
* performed.
*
* @return A logout filter
* @see <a href=
* "https://github.com/spring-projects/spring-security/blob/4.2.3.RELEASE/samples/xml/cas/cassample/src/main/webapp/WEB-INF/applicationContext-security.xml#L43-L49">requestSingleLogoutFilter</a>
*/
@Bean
public LogoutFilter casRequestSingleLogoutFilter() {
LogoutFilter filter = new LogoutFilter( casServer + "/logout",
new SecurityContextLogoutHandler() );
filter.setFilterProcessesUrl( "/logout/cas" );
return filter;
}
/**
* Returns the service properties for CAS.
*
* @return The service properties for CAS
* @see <a href=
* "https://github.com/spring-projects/spring-security/blob/4.2.3.RELEASE/samples/xml/cas/cassample/src/main/webapp/WEB-INF/applicationContext-security.xml#L51-L54">serviceProperties</a>
*/
@Bean
public ServiceProperties casServiceProperties() {
ServiceProperties properties = new ServiceProperties();
properties.setService( casService + "/login" );
properties.setAuthenticateAllArtifacts( true );
return properties;
}
@Bean
public SingleSignOutFilter casSingleLogoutFilter() {
SingleSignOutFilter filter = new SingleSignOutFilter();
filter.setCasServerUrlPrefix( casServer + "/logout" );
filter.setIgnoreInitConfiguration( true );
return filter;
}
}
I can confirm, that after removing the successfulAuthentication
method (Lines 215-240) allows pass through to the super class which behaves as expected. Looking at the history of this file, that section was added to support proxy validation. That said, i am honestly at a loss trying to figure out what this is supposed to do:
boolean continueFilterChain = proxyTicketRequest(serviceTicketRequest(request, response),request);
if(!continueFilterChain) {
super.successfulAuthentication(request, response, chain, authResult);
return;
}
Just reading the code, it seems like it make sense. I would assume that the proxyTicketRequest
would return true if this was a request containing a proxy ticket. However, it does not behave that way. The proxyTicketRequest
method starts by checking if it is a serviceTicketRequest
which makes sense (because if its a service ticket request it is not a proxy ticket request:
if (serviceTicketRequest) {
return false;
}
But the serviceTicketRequest
method simply checks if authentication is required:
private boolean serviceTicketRequest(final HttpServletRequest request,
final HttpServletResponse response) {
boolean result = super.requiresAuthentication(request, response);
if (logger.isDebugEnabled()) {
logger.debug("serviceTicketRequest = " + result);
}
return result;
}
This appears to ignore the fact that authentication already succeeded...
@rwinch , you seem to be the only person committing to the CAS module... Can you shed any light on this? Right now I am creating my own copy of the CasAuthenticationFilter
(cant extend because your method overrides are final
) that removes the successfulAuthentication
override, but that is certainly less than desirable. I would be happy to submit a pull request if i could understand what this code is trying to accomplish...
Hi, the issue still remains.
protected final void successfulAuthentication(successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
does not trigger the onSuccessHandler despite the authentication process being approved. We are using authenticated()
in private boolean proxyTicketRequest(boolean serviceTicketRequest, HttpServletRequest request)
before actually updating authResult
. Even if authResult
is a valid authentication, we are not yet considered authenticated
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 CASAuthenticationFilterfrom
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 alwaystrue
andsuper.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; }
Version
Spring security 3.2.4