Edited at

Spring Boot with Spring Security の Filter 設定とハマりポイント


設定例

Java Configuration で Filter の設定をする際、 org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter を継承して2種類の configure メソッドを上書きするのが便利です。

HttpSecurity で認証用の Filter を追加して、WebSecurity では Filter を無視する設定ができます。


SecurityConfig.java


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

private static final String[] STATIC_RESOURCES = {
"/**/css/**", "/**/js/**", "/**/img/**",
};

@Override
protected void configure(HttpSecurity http) throws Exception {
// Filter を Security Filter Chain に追加
http.addFilter(this.preAuthenticatedProcessingFilter());
}

@Override
public void configure(WebSecurity web) throws Exception {
// Security Filter Chain から除外するパス等を設定
web.ignoring().antMatchers(STATIC_RESOURCES);
}

// Security Filter Chain に登録する Filter は Bean 定義しない
public AbstractPreAuthenticatedProcessingFilter preAuthenticatedProcessingFilter() throws Exception {
final SampleAuthFilter filter = new SampleAuthFilter();
filter.setAuthenticationManager(this.authenticationManager());
return filter;
}
}


この辺りは他の方の記事やサイトがたくさんあるのでわざわざ書かなくても良いのですが、しばらくハマった事があるので書いておきます。


ハマったところ

ignore 設定をしても認証の必要がない静的リソース等を含む全てのリクエストで Filter が適用されてしまうというもの。

数日間、暇を見つけては「spring security ignoring not work」等で検索しまくりましたが、ignore 設定の書き方の問題などで、解決策が見つからずでした。

今思えば、StackOverflow にあったこちらのコメントはまさに解決策だったのですが、気付きませんでした。


原因と解決策

原因は Filter クラスに @Component アノテーションを付けていた事。

Configuration クラスに @Bean を付けるのも同様。

これによって、Security Filter Chain の外にも登録されてしまう。

解決策は当然 Bean として登録させない事。

いくつかのページで @Bean がついているサンプルコードが載っているので、結構同じ問題に悩まされる人もいるのではと思いました。

ただ、未確認ですが Spring Boot(starter-web?) を利用しない場合はこの問題には陥らないのかもしれません。

StackOverFlow で FilterRegistrationBean から除外する解決策からヒントを得て、何とか解決しましたが、WebSecurityConfigurerAdapter のソースから辿っているだけではイマイチ見えてこないわけです。

Hello World で学ぶ Spring Security の仕組み は大変参考になりました。

あと1日解決できなければ、最悪の手段「Filter 側に if 文追加」もチラついていました(笑


参考

Spring Security – security none, filters none, access permitAll

Spring Security filter chain not ignoring specified path [duplicate]

Hello World で学ぶ Spring Security の仕組み