0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

springsecurity。javaconfig。urlとhttpヘッダーの値で、認識有り無しを分岐

Last updated at Posted at 2025-06-16

1. URL だけでの認可分岐(通常の方法)

requestMatchers() は URL や HTTP メソッド(GET、POSTなど)に対するマッチング専用で、HTTP ヘッダーの値を直接見ることはできません。

例1
URLパターン

http
    .authorizeHttpRequests(auth -> auth
    .requestMatchers("/public/**").permitAll()
    .requestMatchers("/admin/**").hasRole("ADMIN")
    .anyRequest().authenticated()
  );

例2

httpメソッドとURLパターン

http
    .authorizeHttpRequests(auth -> auth
    .requestMatchers(HttpMethod.GET, "/api/public/**").permitAll()
    .requestMatchers("/admin/**").hasRole("ADMIN")
    .anyRequest().authenticated()
);

2. HTTP ヘッダーの値で認可を分岐したい場合

これは以下のようにカスタム OncePerRequestFilter を使うことで実現可能です。

例:特定ヘッダー(例: X-API-KEY)の有無で認証をスキップまたは適用

① カスタムフィルターの実装

public class HeaderBasedAuthBypassFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
            throws ServletException, IOException {

        String path = request.getRequestURI();
        String apiKey = request.getHeader("X-API-KEY");

        if (path.startsWith("/external/") && "skip-auth".equals(apiKey)) {
            // 認可対象外にしたい場合
            SecurityContextHolder.clearContext();
        }

        filterChain.doFilter(request, response);
    }
}

② SecurityFilterChain に登録

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .addFilterBefore(new HeaderBasedAuthBypassFilter(), 
         UsernamePasswordAuthenticationFilter.class) // (1)
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/external/**").permitAll() // フィルターで認可制御
            .anyRequest().authenticated()
        );

    return http.build();
}

// (1)

addFilterBeforeは、第1引数に指定したフィルタークラスを第2引数に指定したフィルタークラスより前で動かします。

早い段階で全リクエストを捕まえたい(URL・ヘッダー分岐など)。 認証前(SecurityContextHolder も未初期化)
→ SecurityContextPersistenceFilter.class をaddFilterBeforeの第2引数指定

JWT の検証など、認証処理の前にチェックしたい。認証はされていないが、SecurityContext は初期化済み
→ UsernamePasswordAuthenticationFilter.class をaddFilterBeforeの第2引数指定

すでに認証が済んでいる前提で認可ロジックに関与したい
→ FilterSecurityInterceptor.class をaddFilterBeforeの第2引数指定

HTTP Basic 認証より前
→ BasicAuthenticationFilter.class をaddFilterBeforeの第2引数指定


3. より柔軟な条件分岐にしたい場合

  • Spring Expression Language(SpEL)を access() に使う方法もありますが、ヘッダーには直接アクセスできません。
  • よって、カスタム AuthorizationManager を使う方法もあります(より高度なケース)。

まとめ

条件 方法
URL パターンで分岐 requestMatchers() を使う
ヘッダーの値で分岐 OncePerRequestFilter などのカスタムフィルターを挿入
URL + ヘッダーの複合分岐 カスタムフィルターで両方の条件を判定して、SecurityContext を調整

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?