2014-11-14 75 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。