2014-11-14 74 views
3

我有依赖性的OAuth2用户端弹簧启动应用程序: - 春季启动1.2.0.RC1 - 弹簧安全的oauth2 2.0.4.RELEASE - 弹簧安全3.2.5 .RELEASE春季安全OAuth2用户重定向循环

客户端认证,认证被设定在SecurityContextHolder中,但是当该请求被重定向到原始URL的过滤器链再次开始处理。我注意到,在SecurityContextPersistenceFilter的contextBeforeChainExecution和contextAfterChainExecution都有一个空验证。

我有一些基础的代码[1] Spring Security OAuth2 (google) web app in redirect loop

任何想法,为什么重定向循环?先谢谢你。

[日志片断] https://gist.github.com/yterradas/61da3f6eccc683b3a086

下面是安全的配置。

@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; 
    } 

    } 
}
+0

哪里授权服务器。它的检查令牌端点是否可用(可以卷曲它)? – 2014-11-15 14:57:37

+0

授权服务器是一个独立的组件,不在同一个项目中。是的,我可以卷曲它。我可以看到正在创建的授权,以及启动了保存请求的重定向。我不确定,但我认为背景没有得到保存。认为这是因为Context在执行之前和之后具有空身份验证的原因。 – 2014-11-17 17:47:19

+0

我特别问你是否可以卷曲/ check_token端点。这不是规范的一部分,因此在执行过程中它可能会或可能不会在那里(并且您的客户似乎正在尝试使用它)。 – 2014-11-18 06:52:31

回答

2

我觉得你有2 OAuth2ClientContextFilters(一个由@EnableOAuth2Client添加和手动添加另一个Spring Security的过滤器链)。你应该能够删除你添加的那个。

+0

我已删除从Spring Security的过滤器链'OAuth2ClientContextFilter'但我仍然有重定向循环。让我知道我可以提供哪些其他信息。 – 2014-11-15 14:32:56

0

我发现从而享有除去从SecurityFilterChain几乎每一个过滤器平庸的溶液。不幸的是我没有我工作的应用程序的工作副本。然而,在破坏应用程序之前,应该很容易地通过删除尽可能多的过滤器来复制解决方案,然后仅添加必要的过滤器。如果内存为我服务,那么罪魁祸首就是SecurityContextPersistenceFilter或RequestCacheAwareFilter。