前言
以下是登出遇到問題發現http.cors()不好使,創建CorsFilter也不好使。
: /logout at position 1 of 10 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
: /logout at position 2 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
: /logout at position 3 of 10 in additional filter chain; firing Filter: 'HeaderWriterFilter'
: /logout at position 4 of 10 in additional filter chain; firing Filter: 'LogoutFilter'
需要加上http.cors()纔會有CorsFilter,並且CorsFilter會在LogoutFilter之前。如果沒有CorsFilter或者CorsFilter不在LogoutFilter之前就會出現報錯。
ResourceServerConfig中加上http.cors()是會在FilterChains中第二個的DefaultSecurityFilterChain裏面的LogoutFilter之前產生CorsFilter,但是第一個DefaultSecurityFilterChain始終沒有CorsFilter。
AuthorizationServerSecurityConfiguration order(0),所以第一個DefaultSecurityFilterChain來自於此,但是沒有加入http.cors(),所以找到原因所在。
解決方案一
都加上
ResourceServerConfig:
@Override
public void configure(HttpSecurity http) throws Exception {
http.cors();
//...
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "HEAD", "DELETE", "OPTION"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.addExposedHeader("Authorization");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public CorsFilter corsFilter() {
return new CorsFilter(corsConfigurationSource());
}
兩個都加上
就會下如下圖這樣,除了在springSecurityFilterChain下面有corsFilter,也會在裏面有。
解決方案二
@Configuration
public class CorsFilterConfig {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "HEAD", "DELETE", "OPTION"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.addExposedHeader("Authorization");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public CorsFilter corsFilter() {
return new DefaultCorsFilter(corsConfigurationSource());
}
@Data
static class DefaultCorsFilter extends CorsFilter implements OrderedFilter {
/**
* Constructor accepting a {@link CorsConfigurationSource} used by the filter
* to find the {@link CorsConfiguration} to use for each incoming request.
*
* @param configSource
* @see UrlBasedCorsConfigurationSource
*/
public DefaultCorsFilter(CorsConfigurationSource configSource) {
super(configSource);
}
@Override
public int getOrder() {
return -104;
}
}
}
這樣直接指定corsFilter在springSecurityFilterChain之前
(OrderedRequestContextFilter是-105)
解決方案三
AuthorizationServerConfig:
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer.addTokenEndpointAuthenticationFilter(new CorsFilter(corsConfigurationSource()));
//...
}
ResourceServerConfig
@Override
public void configure(HttpSecurity http) throws Exception {
http.cors();
//...
}
還有很多方式,以上參考