2016-09-25 4 views
0

У меня есть весенняя загрузка + угловое веб-приложение, которое внимательно следит за настройкой этого tutorial: я запускаю сервер авторизации, сервер ресурсов, веб-приложение пользовательского интерфейса, все в том же приложении Spring Boot ,Не удается получить фильтр SSO Spring OAuth для запуска

Затем у меня есть необходимость разрешить пользователю входить в систему со сторонним социальным логином (facebook и т. Д.) И неявно создавать учетные записи пользователей, если использование ранее не регистрировалось.

Я пытался сделать это, следуя следующему учебному пособию here.

В учебнике создание вызова GET /login/facebook приведет к созданию SSOFilter, который был настроен в коде. Но это не происходит с моим собственным кодом. Я попытался изменить порядок фильтра SSO на разные числа, и это тоже не помогло.

В журналах из примера автозапуска учебника. Я вижу следующий вывод:

2016-09-24 22:59:26.728 DEBUG 59433 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/login/facebook' matched by universal pattern '/**' 
2016-09-24 22:59:26.728 DEBUG 59433 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' 
2016-09-24 22:59:26.729 DEBUG 59433 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 
2016-09-24 22:59:26.729 DEBUG 59433 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists 
2016-09-24 22:59:26.729 DEBUG 59433 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created. 
2016-09-24 22:59:26.731 DEBUG 59433 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter' 
2016-09-24 22:59:26.732 DEBUG 59433 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter' 
2016-09-24 22:59:26.736 DEBUG 59433 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter' 
2016-09-24 22:59:26.736 DEBUG 59433 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login/facebook' doesn't match 'POST /logout 
2016-09-24 22:59:26.736 DEBUG 59433 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 6 of 12 in additional filter chain; firing Filter: 'CompositeFilter' 
2016-09-24 22:59:26.737 DEBUG 59433 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/facebook'; against '/login/facebook' 

В моих собственных журналах, я не вижу CompositeFilter когда-либо срабатывает:

2016-09-24 23:38:54.545 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/login/facebook' matched by universal pattern '/**' 
2016-09-24 23:38:54.546 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' 
2016-09-24 23:38:54.547 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 
2016-09-24 23:38:54.547 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter' 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter' 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET] 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/facebook'; against '/logout' 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST] 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login/facebook' doesn't match 'POST /logout 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT] 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login/facebook' doesn't match 'PUT /logout 
2016-09-24 23:38:54.548 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE] 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login/facebook' doesn't match 'DELETE /logout 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher : No matches found 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter' 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.o.p.a.BearerTokenExtractor   : Token not found in headers. Trying request parameters. 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.o.p.a.BearerTokenExtractor   : Token not found in request parameters. Not an OAuth2 request. 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] p.a.OAuth2AuthenticationProcessingFilter : No token in request, will continue chain. 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 
2016-09-24 23:38:54.549 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 
2016-09-24 23:38:54.550 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 
2016-09-24 23:38:54.551 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.sprin[email protected]9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.sprin[email protected]b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 
2016-09-24 23:38:54.551 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter' 
2016-09-24 23:38:54.552 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 
2016-09-24 23:38:54.552 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 
2016-09-24 23:38:54.552 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/facebook'; against '/api/**' 
2016-09-24 23:38:54.552 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Public object - authentication not attempted 
2016-09-24 23:38:54.553 DEBUG 60184 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy  : /login/facebook reached end of additional filter chain; proceeding with original chain 
2016-09-24 23:38:54.571 DEBUG 60184 --- [nio-8080-exec-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /login/facebook 
2016-09-24 23:38:54.571 DEBUG 60184 --- [nio-8080-exec-1] .s.o.p.e.FrameworkEndpointHandlerMapping : Did not find handler method for [/login/facebook] 
2016-09-24 23:38:54.574 DEBUG 60184 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.se[email protected]76f064a2 

Я потянув меня за волосы и все же невежествен, что пошло не так мой код.

Вот фрагменты кода из моей установки:

основной класс файла:

@SpringBootApplication 
public class TuangouApplication extends SpringBootServletInitializer { 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(TuangouApplication.class, args); 
    } 

    // this is for WAR file deployment 
    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(TuangouApplication.class); 
    } 

    @Bean 
    public javax.validation.Validator localValidatorFactoryBean() { 
     return new LocalValidatorFactoryBean(); 
    } 
} 

WebSecurityConfiguration файл. Практически идентичный весеннему урологу oauth2 auth-server пример.

@Configuration 
@EnableOAuth2Client 
@Order(6) 
public class TuangouConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private OAuth2ClientContext oauth2ClientContext; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     // @formatter:off 
     http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**").permitAll() 
      .and().exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")) 
      .and().formLogin().loginPage("/login").failureUrl("/login?error").permitAll() 
      .and().logout().logoutSuccessUrl("/").permitAll() 
      .and().csrf().csrfTokenRepository(csrfTokenRepository()) 
      .and().addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class); 
     // @formatter:on 
    } 

// @Order(Ordered.HIGHEST_PRECEDENCE) 
    @Configuration 
    @EnableGlobalMethodSecurity(prePostEnabled=true) 
    protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter { 

     @Override 
     public void init(AuthenticationManagerBuilder auth) throws Exception { 
      auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder()); 
     } 

     @Bean 
     public UserDetailsService userDetailsService() { 
      return new DatabaseUserServiceDetails(); 
     } 
    } 

    private Filter csrfHeaderFilter() { 
     return new OncePerRequestFilter() { 
      @Override 
      protected void doFilterInternal(HttpServletRequest request, 
        HttpServletResponse response, FilterChain filterChain) 
          throws ServletException, IOException { 
       CsrfToken csrf = (CsrfToken) request 
         .getAttribute(CsrfToken.class.getName()); 
       if (csrf != null) { 
        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN"); 
        String token = csrf.getToken(); 
        if (cookie == null 
          || token != null && !token.equals(cookie.getValue())) { 
         cookie = new Cookie("XSRF-TOKEN", token); 
         cookie.setPath("/"); 
         response.addCookie(cookie); 
        } 
       } 
       filterChain.doFilter(request, response); 
      } 
     }; 
    } 

    private CsrfTokenRepository csrfTokenRepository() { 
     HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); 
     repository.setHeaderName("X-XSRF-TOKEN"); 
     return repository; 
    } 

    @Bean 
    public FilterRegistrationBean oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) { 
     FilterRegistrationBean registration = new FilterRegistrationBean(); 
     System.out.println("### foobar"); 
     registration.setFilter(filter); 
     registration.setOrder(-100); 
     return registration; 
    } 

    @Bean 
    @ConfigurationProperties("github") 
    public ClientResources github() { 
     return new ClientResources(); 
    } 

    @Bean 
    @ConfigurationProperties("facebook") 
    public ClientResources facebook() { 
     return new ClientResources(); 
    } 

    private Filter ssoFilter() { 
     CompositeFilter filter = new CompositeFilter(); 
     List<Filter> filters = new ArrayList<Filter>(); 
     filters.add(ssoFilter(facebook(), "/login/facebook")); 
     filters.add(ssoFilter(github(), "/login/github")); 
     filter.setFilters(filters); 
     return filter; 
    } 

    private Filter ssoFilter(ClientResources client, String path) { 
     OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(
       path); 
     OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext); 
     filter.setRestTemplate(template); 
     filter.setTokenServices(new UserInfoTokenServices(
       client.getResource().getUserInfoUri(), client.getClient().getClientId())); 
     return filter; 
    } 
} 

class ClientResources { 

    @NestedConfigurationProperty 
    private AuthorizationCodeResourceDetails client = new AuthorizationCodeResourceDetails(); 

    @NestedConfigurationProperty 
    private ResourceServerProperties resource = new ResourceServerProperties(); 

    public AuthorizationCodeResourceDetails getClient() { 
     return client; 
    } 

    public ResourceServerProperties getResource() { 
     return resource; 
    } 
} 

Авторизация сервера конфигурации:

@Configuration 
@EnableAuthorizationServer 
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    private AuthenticationManager auth; 

    @Autowired 
    private DataSource dataSource; 

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 

    @Bean 
    public JdbcTokenStore tokenStore() { 
     return new JdbcTokenStore(dataSource); 
    } 

    @Bean 
    protected AuthorizationCodeServices authorizationCodeServices() { 
     return new JdbcAuthorizationCodeServices(dataSource); 
    } 

    @Override 
    public void configure(AuthorizationServerSecurityConfigurer security) 
      throws Exception { 
     security.passwordEncoder(passwordEncoder); 
    } 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) 
      throws Exception { 
     endpoints.authorizationCodeServices(authorizationCodeServices()) 
       .authenticationManager(auth).tokenStore(tokenStore()) 
       .approvalStoreDisabled(); 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     // @formatter:off 
     clients.jdbc(dataSource).passwordEncoder(passwordEncoder); 
//   .withClient("grubmarket") 
//    .authorizedGrantTypes("password", "authorization_code", "client_credentials", 
//      "refresh_token", "implicit") 
//    .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") 
//    .scopes("read", "write", "trust") 
//    .resourceIds("oauth2-resource") 
//    .accessTokenValiditySeconds(3600); 
     // @formatter:on 
    } 
} 

ресурсов конфигурации сервера:

@Configuration 
@EnableResourceServer 
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{ 

    @Autowired 
    private TokenStore tokenStore; 

    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) 
      throws Exception { 
     resources.tokenStore(tokenStore); 
    } 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     // @formatter:off 
     http.antMatcher("/**").authorizeRequests().antMatchers("/api/**").permitAll(); 
//  http.antMatcher("/api/**").authorizeRequests().antMatchers(HttpMethod.GET, "/api/deals").permitAll().anyRequest().authenticated(); 
     // @formatter:on 
    } 
} 

ответ

0

по умолчанию @Order для org.springframework.security.oauth2.config.annotation.web.configuration.ResourcererverConfiguration является 3.

Ваш TuangouConfiguration установлен с @Order(6). Поэтому, если вы измените его на @Order(2), ssoFilter или CompositeFilter будут вызываться по запросу GET /login/facebook

+0

Это сработало! Где я могу найти порядок по умолчанию для различных фильтров? Можно ли распечатать или зарегистрировать относительный порядок всех фильтров при запуске программы? –

+0

Заказ по умолчанию для цепочки фильтров пружинной защиты, созданный '@ EnableResourceServer', указан в коде javadoc ... ... (3). Кроме того, вы можете отлаживать порядок фильтров в своей соответствующей цепочке, переопределяя следующее в вашей 'TuangouConfiguration' ...' public void configure (WebSecurity web) throws Exception { \t \t web.debug (true); \t} ' –

+0

Еще одна важная конфигурация, которую нужно отметить:' HttpSecurity.antMatcher() '.Я заметил, что вы используете это в «TuangouConfiguration» и «ResourceServerConfiguration», но оба они совпадают на '/ **'. Я бы рекомендовал использовать более конкретный шаблон в 'ResourceServerConfiguration', например'/api/** '. Это также сработает и позволит вам вызывать 'ssoFilter', когда запрос будет'/login/facebook', и устранит необходимость использования @Order на вашей «TuangouConfiguration». Я настоятельно рекомендую использовать этот подход к настройке. –

Смежные вопросы