特定のAPI呼び出しにキャプチャフィルターを追加する非侵襲的な方法を探しています。
私のセットアップは2つのWebSecurityConfigurerAdapters
で構成され、それぞれに1つのフィルターがあります(キャプチャフィルターではありません)。
パブリック、内部API、または外部API呼び出しで、SpringSecurity関連のフィルター before を追加するにはどうすればよいですか? SecurityContextは必要ありません。リクエストヘッダーでキャプチャを確認するか、filterChain(通常のフィルター)に転送するか、手動でアクセスを拒否する必要があります。 web.xmlでフィルターを宣言しようとしましたが、依存性注入を使用できなくなります。
これが私のSpringセキュリティ構成です:
@EnableWebSecurity
public class SpringSecurityConfig {
@Configuration
@Order(1)
@EnableGlobalMethodSecurity(securedEnabled = true)
public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private Filter filterA;
public InternalApiConfigurerAdapter() {
super(true);
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/public/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/iapi/**")
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(filterA, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return authenticationManager();
}
}
@Configuration
@Order(2)
@EnableGlobalMethodSecurity(securedEnabled = true)
public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private FilterB filterB;
public ExternalApiConfigurerAdapter() {
super(true);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/external/**")
.exceptionHandling().and()
.anonymous().and()
.servletApi().and()
.authorizeRequests()
.anyRequest().authenticated().and()
.addFilterBefore(filterB, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return authenticationManager();
}
}
更新:現在、web.xmlで宣言されたフィルターを使用した作業構成があります。ただし、Springコンテキストから分離されるという欠点があるため(たとえば、Beanの自動配線がない)、Springを活用するより良いソリューションを探しています。
概要:残りの2つの問題があります。
UsernamePasswordAuthenticationFilter
の前にフィルターAとBが挿入された作業構成が既にあるので、別のカスタムフィルターを簡単に追加できるはずです。
まず、フィルターを作成し、それをBeanとして宣言し、クラスに_@Component
_で注釈を付けるか、_@Bean
_クラス内の_@Configuration
_として宣言します。これにより、フィルターを挿入する準備が整います。 _@Autowired
_。
これで、フィルターAおよびBとして注入し、使用することができます。 Spring Securityリファレンスドキュメントの Filter Ordering セクションによると、チェーンの最初のフィルターはChannelProcessingFilter
であるため、SpringSecurityフィルターの何よりも先にフィルターを挿入します。チェーン、あなたはこれをするでしょう:
_@Autowired
private CaptchaFilter captchaFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/iapi/**")
.addFilterBefore(captchaFilter, (Class<? extends Filter>) ChannelProcessingFilter.class)
.addFilterBefore(filterA, (Class<? extends Filter>) UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.anyRequest().authenticated();
}
_
ちなみに、exceptionHandling()
anonymous()
とservletApi()
は、WebSecurityConfigurerAdapter
を拡張するときに、anonymous()
実際に構成の詳細を指定する場合は、 HttpSecurity
javadoc
SpringSecurityの「エントリポイント」であるDelegatingFilterProxy
は引き続きフィルターの前に実行されますが、このコンポーネントはチェーンの最初のフィルター(この場合はCaptchaFilter)にのみ要求を委任することに注意してください。したがって、SpringSecurityの他の何よりも先にフィルターを実行することになります。
ただし、DelegatingFilterProxy
の前にキャプチャフィルターを実行する必要がある場合は、Spring Security構成で実行する方法がないため、_web.xml
_ファイルで宣言する必要があります。
更新:他の構成にキャプチャフィルターを含めたくない場合は、いつでも3番目の構成を追加でき、構成クラスは次のようになります。
_@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringSecurityConfig {
@Configuration
@Order(1)
public static class CaptchaApiConfigurerAdatper extends WebSecurityConfigurerAdapter {
@Autowired
private CaptchaFilter captchaFilter;
public CaptchaApiConfigurerAdatper() {
super(true);
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/public/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers()
.antMatcher("/iapi/captcha**")
.antMatcher("/external/captcha**")
.and()
.addFilterBefore(captchaFilter, (Class<? extends Filter>) ChannelProcessingFilter.class)
.authorizeRequests()
.anyRequest().authenticated();
}
}
@Configuration
@Order(2)
public static class InternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
// ommiting code for the sake of clarity
}
@Configuration
@Order(3)
public static class ExternalApiConfigurerAdapter extends WebSecurityConfigurerAdapter {
// ommiting code for the sake of clarity
}
_
ちなみに、別のヒントとして、特定の構成以外のすべての一般的な構成を、@EnableGlobalMethodSecurity(securedEnabled = true)
AuthenticationManager、WebSecurity
などのメインクラスにリファクタリングして、パブリックのセキュリティをスキップできますが、メインクラスは何も拡張していないので、メソッド宣言を_@Autowire
_する必要があります。
WebSecurity
には1つの問題がありますが、_/public/**
_を無視している場合は、HttpSecurity
と_/public/captcha**
_のマッチャーは無視されるので、そうすべきではありません。 WebSecurity
をリファクタリングし、CaptchaConfigクラスで異なるパターンを使用して、重複しないようにします。