无法触发 Spring OAuth SSO 过滤器
Can not get Spring OAuth SSO filter to trigger
我有一个 spring 引导 + angular 网络应用程序,它与此 tutorial 的设置密切相关:我是 运行 授权服务器,资源服务器,UI Web 应用程序都在同一个 Spring 启动应用程序中。
然后我需要允许用户使用第三方社交登录(facebook 等)登录并隐式创建用户帐户(如果用户之前未注册)。
我试图通过学习另一个教程来实现这一点 here。
在教程中,进行 GET /login/facebook
调用会触发在代码中设置的 SSOFilter。但我自己的代码不会发生这种情况。我尝试将 SSO 过滤器的顺序更改为不同的数字,但也没有帮助。
在教程 auth-server 示例的日志中。我看到以下输出:
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.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@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.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@76f064a2
我正在扯头发,但仍然不知道我的代码出了什么问题。
这是我的设置代码片段:
主要 class 文件:
@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();
}
}
Web 安全配置文件。
几乎与 spring 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
}
}
org.springframework.security.oauth2.config.annotation.web.configuration.ResourcererverConfiguration
的默认 @Order
是 3。
您的 TuangouConfiguration
设置为 @Order(6)
。因此,如果您将其更改为 @Order(2)
,当请求为 GET /login/facebook
时,将调用 ssoFilter 或 CompositeFilter
我有一个 spring 引导 + angular 网络应用程序,它与此 tutorial 的设置密切相关:我是 运行 授权服务器,资源服务器,UI Web 应用程序都在同一个 Spring 启动应用程序中。
然后我需要允许用户使用第三方社交登录(facebook 等)登录并隐式创建用户帐户(如果用户之前未注册)。
我试图通过学习另一个教程来实现这一点 here。
在教程中,进行 GET /login/facebook
调用会触发在代码中设置的 SSOFilter。但我自己的代码不会发生这种情况。我尝试将 SSO 过滤器的顺序更改为不同的数字,但也没有帮助。
在教程 auth-server 示例的日志中。我看到以下输出:
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.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@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.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@76f064a2
我正在扯头发,但仍然不知道我的代码出了什么问题。
这是我的设置代码片段:
主要 class 文件:
@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();
}
}
Web 安全配置文件。
几乎与 spring 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
}
}
org.springframework.security.oauth2.config.annotation.web.configuration.ResourcererverConfiguration
的默认 @Order
是 3。
您的 TuangouConfiguration
设置为 @Order(6)
。因此,如果您将其更改为 @Order(2)
,当请求为 GET /login/facebook
CompositeFilter