0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qiita第2投稿!なぜ Spring Security と JWT を混同してはいけないのか?【Spring編】

Last updated at Posted at 2025-10-26

Qiita第2投稿!なぜ Spring Security と JWT を混同してはいけないのか?【Spring編】

こんにちは!前回の投稿では PURGE と TRUNCATE の違い(Oracle編) について整理しましたが、
今回は Java/Spring 界隈でよく話題になる 「Spring Security」と「JWT」 の違いについて書いてみようと思います。

Spring を使って開発していると、認証まわりの話で
「Spring Security と JWT、どっちを使えばいいの?」
「Spring Security = JWT のことじゃないの?」
といった質問をよく耳にします。

実際にはこの2つは まったく別のレイヤーの技術 です。
混同してしまうと、セキュリティ設計を誤る可能性もあるので注意が必要です。


Spring Securityとは?

Spring Security は、Spring Framework 向けの セキュリティフレームワーク です。
主に次のような機能を提供します:

  • 認証(Authentication)
  • 認可(Authorization)
  • CSRF 対策
  • セッション管理
  • パスワードの暗号化
  • Security Filter Chain の構築

要するに、アプリケーション全体のセキュリティを制御する仕組みです。
Spring Boot でアプリを立ち上げたとき、自動的に /login ページが出てくるのはこの仕組みのおかげです。


JWTとは?

JWT (JSON Web Token) は、認証情報をトークンとしてやり取りするための フォーマット です。

一方、Spring Security は「認証と認可をどう制御するか」という仕組みそのものです。


Spring Security と JWT の関係

実は、Spring Security は JWT を使って動くこともできる のです。
Spring Security は “認証方法” を自由に差し替えられるように設計されています。

たとえば:

  • セッションベースの認証(従来型 Web アプリ)
  • JWT ベースのトークン認証(SPA + REST API)
  • OAuth2 / OpenID Connect 認証(Google, GitHub ログインなど)

このように、
Spring Security = フレームワーク, JWT = データ形式
という役割分担になります。


🧩 簡単な設定例(Spring Boot 3.x × Spring Security × JWT コード整理)

この記事では、Spring Boot 3.x と JWT 認証を Spring Security で組み合わせる場合の コード部分だけを整理 して説明します。
全体像が理解しやすいように 説明 + コード 形式にしています。

1️⃣ build.gradle (依存関係)

下記の依存関係を追加してください。

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
}

🔹 Spring Boot 3.x + JJWT 最新 0.11.x 版
🔹 jjwt-impl と jjwt-jackson は実行時に必要

2️⃣ JWT 認証フィルター (JwtAuthenticationFilter.java)

Spring Boot 3.x + JJWT 0.11.x の方式です。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final String SECRET_KEY = "my-secret-key-my-secret-key"; // 最低 256bit 推奨

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

        String authHeader = request.getHeader("Authorization");

        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String jwt = authHeader.substring(7);
            try {
                // parserBuilder() を使用
                Jws<Claims> claimsJws = Jwts.parserBuilder()
                        .setSigningKey(Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8)))
                        .build()
                        .parseClaimsJws(jwt);

                String username = claimsJws.getBody().getSubject();

                // 認証情報をセット(権限なし)
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(username, null, List.of());
                SecurityContextHolder.getContext().setAuthentication(authentication);

            } catch (Exception e) {
                System.out.println("Invalid JWT: " + e.getMessage());
            }
        }

        filterChain.doFilter(request, response);
    }
}

🔹 javax.servlet.(Springboot2.x) → jakarta.servlet. に変更
🔹 最低 256bit 以上のキーが必要

3️⃣ Security 設定 (SecurityConfig.java)

Spring Security 6.x での推奨設定です。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthenticationFilter;

    public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                .csrf(csrf -> csrf.disable()) // CSRF 無効化
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/auth/**").permitAll() // 認証不要
                        .anyRequest().authenticated()           // その他は認証必要
                )
                .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }
}

🔹 WebSecurityConfigurerAdapter は不要
🔹 JWT フィルターは UsernamePasswordAuthenticationFilter の前に配置


重要ポイント

  1. Spring Security
    フレームワークとして JWT 認証を接続する役割。

  2. JWT
    認証情報を運ぶデータフォーマット。

  3. Spring Boot 3.x + JJWT 0.11.x での注意点

    1. parserBuilder() を使用すること
    2. jakarta.servlet パッケージを使用
    3. SecurityFilterChain Bean を必ず定義すること
    4. HMAC SHA256 用に最低 256bit のキーを使用すること

5. よくある誤解

誤解 正しい理解
Spring Security = JWT ❌ Spring Security は JWT を使うこともできるセキュリティフレームワーク
JWT があれば Spring Security は不要 ❌ JWT は認証情報を運ぶだけ。検証や認可は別途実装が必要
JWT を使えば自動的に安全になる ❌ 有効期限管理や署名検証などの正しい実装が必須

まとめ

項目 Spring Security JWT
種類 フレームワーク トークンフォーマット
主な役割 認証・認可・セキュリティ全般の制御 認証情報の伝達
状態管理 セッション or Stateless Stateless
関係性 JWTを利用可能 Spring Securityと組み合わせて使うことが多い

おわりに

Spring Security と JWT は、よく一緒に語られるテーマですが、
同じものではなく、補完関係にある という点を理解しておくことが大切です。

次回は「Spring Security で JWT 認証を実装してみる」記事を書こうと思っています。
興味がある方はぜひフォローしていただけると嬉しいです! 😊

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?