最新の安定バージョンについては、Spring Security 6.5.0 を使用してください! |
FilterSecurityInterceptor で HttpServletRequest を認証する
|
このセクションは、サーブレットベースのアプリケーション内で認可がどのように機能するかを深く掘り下げて、サーブレットのアーキテクチャと実装に基づいています。
FilterSecurityInterceptor
(Javadoc) は、HttpServletRequest
インスタンスの認可を提供します。セキュリティフィルターの 1 つとして FilterChainProxy に挿入されます。
次のイメージは、FilterSecurityInterceptor
のロールを示しています。
FilterSecurityInterceptor
は、SecurityContextHolder から認証を取得します。 FilterSecurityInterceptor
は、FilterSecurityInterceptor
に渡される HttpServletRequest
、HttpServletResponse
、FilterChain
から FilterInvocation
(Javadoc) を作成します。 FilterInvocation
を SecurityMetadataSource
に渡して、ConfigAttribute
を取得します。 Authentication
、FilterInvocation
、ConfigAttribute
を AccessDecisionManager
に渡します。 認可が拒否された場合、AccessDeniedException
がスローされます。この場合、ExceptionTranslationFilter
は AccessDeniedException
を処理します。 アクセスが認可されると、FilterSecurityInterceptor
は FilterChain
を続行します。これにより、アプリケーションは正常に処理されます。
デフォルトでは、Spring Security の認可では、すべてのリクエストを認証する必要があります。次のリストは、明示的な構成を示しています。
優先順位の順にルールを追加することで、異なるルールを持つように Spring Security を構成できます。
Java
XML
Kotlin
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.authorizeRequests(authorize -> authorize (1)
.requestMatchers("/resources/**", "/signup", "/about").permitAll() (2)
.requestMatchers("/admin/**").hasRole("ADMIN") (3)
.requestMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") (4)
.anyRequest().denyAll() (5)
);
return http.build();
}
<http> (1)
<!-- ... -->
(2)
<intercept-url pattern="/resources/**" access="permitAll"/>
<intercept-url pattern="/signup" access="permitAll"/>
<intercept-url pattern="/about" access="permitAll"/>
<intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/> (3)
<intercept-url pattern="/db/**" access="hasRole('ADMIN') and hasRole('DBA')"/> (4)
<intercept-url pattern="/**" access="denyAll"/> (5)
</http>
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeRequests { (1)
authorize("/resources/**", permitAll) (2)
authorize("/signup", permitAll)
authorize("/about", permitAll)
authorize("/admin/**", hasRole("ADMIN")) (3)
authorize("/db/**", "hasRole('ADMIN') and hasRole('DBA')") (4)
authorize(anyRequest, denyAll) (5)
}
}
return http.build()
}
1 | 複数の認可ルールが指定されています。各ルールは、宣言された順序で考慮されます。 |
2 | すべてのユーザーがアクセスできる複数の URL パターンを指定しました。具体的には、URL が "/resources/" で始まるか、"/signup" に等しいか、"/about" に等しい場合、すべてのユーザーがリクエストにアクセスできます。 |
3 | "/admin/" で始まる URL は、"ROLE_ADMIN" のロールを持つユーザーに制限されます。hasRole メソッドを呼び出しているため、"ROLE_" プレフィックスを指定する必要がないことに気付くでしょう。 |
4 | "/db/" で始まる URL には、ユーザーが "ROLE_ADMIN" と "ROLE_DBA" の両方を持っている必要があります。hasRole 式を使用しているため、"ROLE_" プレフィックスを指定する必要がないことに気付くでしょう。 |
5 | まだ一致していない URL はアクセスを拒否されます。これは、認可規則の更新を誤って忘れたくない場合に適した戦略です。 |
ディスパッチャー型を使用して FilterSecurityInterceptor を構成する
デフォルトでは、FilterSecurityInterceptor
はすべてのリクエストに適用されます。これは、すでにフィルタリングされたリクエストからリクエストがディスパッチされた場合、FilterSecurityInterceptor
はディスパッチされたリクエストに対して同じ認可チェックを実行することを意味します。一部のシナリオでは、一部のディスパッチャー型に認可を適用したくない場合があります。
Java
XML
@Bean
SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.authorizeRequests((authorize) -> authorize
.dispatcherTypeMatchers(DispatcherType.ASYNC, DispatcherType.ERROR).permitAll()
.anyRequest.authenticated()
)
// ...
return http.build();
}
<http auto-config="true">
<intercept-url request-matcher-ref="dispatcherTypeMatcher" access="permitAll" />
<intercept-url pattern="/**" access="authenticated"/>
</http>
<b:bean id="dispatcherTypeMatcher" class="org.springframework.security.web.util.matcher.DispatcherTypeRequestMatcher">
<b:constructor-arg value="ASYNC"/>
<b:constructor-arg value="ERROR"/>
</b:bean>