2014-11-14 2 views
3

OAuth2를 리디렉션 : - 봄 부팅을 1.2.0.RC1 - 봄 - 보안 OAuth2를 2.0.4.RELEASE - 봄 보안 3.2.5 클라이언트가 인증하고 인증이 SecurityContextHolder에 설정되지만 요청이 원래 URL로 리디렉션되면 필터 체인이 다시 처리를 시작합니다. 나는 SecurityContextPersistenceFilter에서 contextBeforeChainExecution과 contextAfterChainExecution 둘 다 null 인증을 가지고있는 것으로 나타났습니다.봄 보안 내가 종속성에 OAuth2를 클라이언트 스프링 부팅 응용 프로그램이 루프

나는에 일부 코드를 기반으로 한 [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

권한 서버는 어디에 있습니까? 체크 토큰 종점을 사용할 수 있습니까 (컬 할 수 있습니까)? –

+0

권한 서버는 동일한 프로젝트가 아닌 별도의 구성 요소입니다. 예, 저는 그것을 말릴 수 있습니다. 생성 된 권한을 볼 수있을뿐만 아니라 저장된 요청으로 리디렉션이 시작됩니다. 나는 확실하지 않지만 컨텍스트가 저장되지 않는다고 생각합니다. 실행 전후의 컨텍스트가 널 인증을 가지고 있기 때문에 생각할 수있는 이유. –

+0

/check_token 끝점을 말릴 수 있는지 구체적으로 물었습니다. 그것은 사양의 일부가 아니므로 구현에 따라 다르거 나 없을 수도 있습니다 (그리고 클라이언트가이를 사용하려고하는 것으로 보입니다). –

답변

2

나는 당신이 2 OAuth2ClientContextFilters을 (하나 @EnableOAuth2Client 추가하고 당신이 봄 보안 필터 체인에 수동으로 서로를 추가 한) 생각. 추가 한 항목을 제거 할 수 있어야합니다.

+0

스프링 보안 필터 체인에서'OAuth2ClientContextFilter'를 제거했지만 여전히 리다이렉트 루프가 있습니다. 제가 제공 할 수있는 다른 정보를 알려주십시오. –

0

SecurityFilterChain에서 거의 모든 필터를 제거해야하는 평범한 솔루션을 발견했습니다. 불행히도 나는 작업 한 응용 프로그램의 작업 복사본이 없습니다. 그러나 응용 프로그램을 중단하고 필요한 필터 만 추가하기 전에 가능한 많은 필터를 제거하여 솔루션을 복제하는 것이 쉬워야합니다. 메모리가 바로 저에게 봉사한다면 범인은 SecurityContextPersistenceFilter 또는 RequestCacheAwareFilter 중 하나입니다.