I have a oauth2 client spring-boot application with dependencies: - spring-boot 1.2.0.RC1 - spring-security-oauth2 2.0.4.RELEASE - spring-security 3.2.5.RELEASE
The client authenticates, the authentication is set in the SecurityContextHolder but when the request is redirected to the original url the filter chain starts processing again. I noticed that in the SecurityContextPersistenceFilter
the contextBeforeChainExecution and contextAfterChainExecution both have a null authentication.
I have based some of the code on [1]Spring Security OAuth2 (google) web app in redirect loop
Any ideas as to why the redirect loop? Thank you in advance.
[Logs snippet]https://gist.github.com/yterradas/61da3f6eccc683b3a086
Below is the config for security.
@Configuration public class SecurityConfig { @Configuration @EnableWebMvcSecurity protected static class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationProcessingFilter; @Autowired private LoginUrlAuthenticationEntryPoint vaultAuthenticationEntryPoint; @SuppressWarnings({"SpringJavaAutowiringInspection"}) @Autowired private OAuth2ClientContextFilter oAuth2ClientContextFilter; @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off http .authorizeRequests() .antMatchers("/**").authenticated() .and() .exceptionHandling().authenticationEntryPoint(vaultAuthenticationEntryPoint) .and() .addFilterAfter(oAuth2ClientContextFilter, ExceptionTranslationFilter.class) .addFilterBefore(oAuth2ClientAuthenticationProcessingFilter, FilterSecurityInterceptor.class) .anonymous().disable(); // @formatter:on } @Override public void configure(WebSecurity web) throws Exception { // @formatter:off web /* TODO: disable debug in production */ .debug(true); // @formatter:on } } @Configuration @EnableOAuth2Client protected static class ClientSecurityConfig { @Value("${app.name}") private String appId; @Value("${app.clientId}") private String appClientId; @Value("${app.clientSecret}") private String appClientSecret; @Value("${app.redirectUrl}") private String appRedirectUrl; @Value("${vault.accessTokenUrl}") private String vaultAccessTokenUrl; @Value("${vault.userAuthorizationUrl}") private String vaultUserAuthorizationUrl; @Value("${vault.checkTokenUrl}") private String vaultCheckTokenUrl; @SuppressWarnings({"SpringJavaAutowiringInspection"}) @Resource @Qualifier("oauth2ClientContext") private OAuth2ClientContext oAuth2ClientContext; @Autowired @Qualifier("securityDataSource") private DataSource securityDataSource; @Autowired private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter; @Bean public OAuth2RestOperations oAuth2RestOperations() { AccessTokenProviderChain provider = new AccessTokenProviderChain( Arrays.asList(new AuthorizationCodeAccessTokenProvider()) ); provider.setClientTokenServices(new JdbcClientTokenServices(securityDataSource)); OAuth2RestTemplate template = new OAuth2RestTemplate(oAuth2Resource(), oAuth2ClientContext); template.setAccessTokenProvider(provider); template.setMessageConverters(Arrays.asList(jackson2HttpMessageConverter)); return template; } @Bean OAuth2ProtectedResourceDetails oAuth2Resource() { AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails(); resource.setId(appId); resource.setAuthenticationScheme(AuthenticationScheme.query); resource.setAccessTokenUri(vaultAccessTokenUrl); resource.setUserAuthorizationUri(vaultUserAuthorizationUrl); resource.setUseCurrentUri(false); resource.setPreEstablishedRedirectUri(appRedirectUrl); resource.setClientId(appClientId); resource.setClientSecret(appClientSecret); resource.setClientAuthenticationScheme(AuthenticationScheme.form); return resource; } @Bean ResourceServerTokenServices oAuth2RemoteTokenServices() { VaultTokenServices tokenServices = new VaultTokenServices(); RestTemplate restOperations = new RestTemplate(); restOperations.setMessageConverters(Arrays.asList(jackson2HttpMessageConverter)); tokenServices.setRestTemplate(restOperations); tokenServices.setClientId(appClientId); tokenServices.setClientSecret(appClientSecret); tokenServices.setCheckTokenEndpointUrl(vaultCheckTokenUrl); return tokenServices; } @Bean LoginUrlAuthenticationEntryPoint oAuth2AuthenticationEntryPoint() { return new LoginUrlAuthenticationEntryPoint("/vaultLogin"); } @Bean OAuth2ClientAuthenticationProcessingFilter oAuth2ClientAuthenticationProcessingFilter() { OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter("/vaultLogin"); filter.setRestTemplate(oAuth2RestOperations()); filter.setTokenServices(oAuth2RemoteTokenServices()); return filter; } } }
I think you have 2 OAuth2ClientContextFilters
(one is added by @EnableOAuth2Client
and you have added another manually to the Spring Security filter chain). You should be able to remove the one you added.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With