Contents
Spring Boot マイクロサービスにおける認証実装の体系的解説
Spring Bootマイクロサービスでセキュアな認証を構築するには、Spring SecurityとOAuth2が不可欠です。本記事ではSpring Boot マイクロサービス 認証 実装 方法について、導入から実践まで体系的に解説します。特に分散環境でのセキュリティリスクの回避やトークンベース認証の設計ポイントをわかりやすくまとめます。
マイクロサービスアーキテクチャにおける認証の重要性
マイクロサービスでは、各サービスが独立して運用されるため、統一された認証仕組みが必須です。分散環境では、サービス間でユーザー情報やアクセス権限を共有しにくいという課題があり、適切な認証設計がセキュリティの基盤となります。
分散環境でのセキュリティリスク
マイクロサービスアーキテクチャにおいては、以下のようなリスクがあります。
- サービス間通信の不正利用:外部からアクセス可能なAPIを適切に保護しないと、悪意のあるユーザーがデータを改ざんする可能性があります。
- 認証情報の漏洩:各サービスごとにユーザー情報を保存すると、一元管理が困難になり、セキュリティホールが生じやすくなります。
認証と認可の役割分離
認証(Auth)は「誰であるか」を確認し、認可(Authorization)は「何ができるか」を決定します。マイクロサービスでは、認証は中央の認証サーバーで一括処理し、各リソースサーバーが認可を担当するのが効果的です。
Spring Securityの基本設定フロー
Spring BootマイクロサービスにSpring Securityを導入するには、依存関係追加とセキュリティコンフィグレーションの2つの手順が必要です。ここでは実装例を交えながら解説します。
依存関係の追加方法
pom.xmlに以下のような依存関係を記載します。
|
1 2 3 4 5 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> |
Spring SecurityはデフォルトですべてのHTTPリクエストを保護するため、初期状態では401エラーが発生します。これはセキュリティ設定が完了していないことを示しています。
セキュリティコンフィグレーションクラス構成
Spring Boot 2.7以降はWebSecurityConfigurerAdapterの使用が非推奨となったため、以下のようにSecurityFilterChainを定義します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/api/public/**").permitAll() .anyRequest().authenticated()) .formLogin(login -> login.disable()) .httpBasic(basic -> basic.disable()); return http.build(); } } |
上記コードでは、/api/public/**のパスは認証不要とし、それ以外のリクエストには認証を必須にしています。この設定をベースにJWTやOAuth2を導入する準備ができました。
JWTトークンの発行・検証手順
JWT(JSON Web Token)は、マイクロサービス間でユーザー情報を安全に共有できる仕組みです。ここでは発行と検証の手順を実装例とともに解説します。
JWT生成処理の実装例
JWTトークンを発行する際には、jjwtライブラリを使用するのが一般的です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; public class JwtUtil { private static final String SECRET_KEY = "your-secret-key"; // ⚠️ 非推奨: 環境変数等で管理すべき public static String generateToken(String username) { return Jwts.builder() .setSubject(username) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } } |
⚠️ 重要:
your-secret-keyはハードコーディングを避け、System.getenv("JWT_SECRET")やキーマネジメントシステムを使用してください。
トークン検証ロジックの設計
トークンの有効性を確認するには、以下の処理が必要です。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public class JwtUtil { public static boolean validateToken(String token) { try { Jwts.parserBuilder().setSigningKey(SECRET_KEY).build().parseClaimsJws(token); return true; } catch (JwtException e) { // トークンが無効な場合の処理 return false; } } } |
このように、トークンの署名検証と有効期限チェックを行うことで不正アクセスを防ぎます。
OAuth2 Client/Resource Serverの構成方法
OAuth2は、外部認証サーバーとの連携に最適なプロトコルです。ここではクライアントとリソースサーバーの設定方法を解説します。
認証サーバーとの連携設定
Spring Security OAuth2 Clientモジュールを使用すると、外部認証サーバー(例:Auth0やKeycloak)と簡単に連携できます。
|
1 2 3 4 5 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> |
application.ymlに認証サーバーの情報を記載します。
|
1 2 3 4 5 6 7 8 9 10 |
spring: security: oauth2: client: registration: google: # ⚠️ ユーザーは自身のregistration IDに置き換えること client-id: your-google-client-id client-secret: your-google-client-secret scope: email, profile |
⚠️ 注意:
リソースサーバーとしての構成
リソースサーバーでは、OAuth2トークンの検証を行います。以下はSpring Security OAuth2 Resource Serverモジュールの例です。
|
1 2 3 4 5 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> |
application.ymlに設定を追加します。
|
1 2 3 4 5 6 7 |
spring: security: oauth2: resourceserver: jwt: issuer-uri: https://your-auth-server.com/realms/your-realm # ⚠️ イシュアURIは認証サーバーに合わせて指定 |
Spring Bootバージョンとの互換性について
Spring SecurityやOAuth2モジュールの挙動はバージョンによって大きく異なります。以下の表を参考に、自分のプロジェクトで使用するSpring Bootバージョンと互換性のある依存関係を導入してください。
|
1 2 3 4 5 6 |
| Spring Boot バージョン | 推奨Spring Securityバージョン | OAuth2 Clientモジュールの注意点 | |------------------------|-------------------------------|------------------------------| | 3.0.x | 6.1.x | **OAuth2 Clientは非推奨**、OAuth2 Resource Serverモジュールを優先 | | 2.7.x | 5.7.x | `WebSecurityConfigurerAdapter`が非推奨、`SecurityFilterChain`を採用 | | 2.6.x以下 | 5.6.x | `oauth2-client`モジュールでOAuth2認証の導入可能 | |
Spring Boot 3.0以降ではOAuth2 Clientモジュールは非推奨になりました。代わりにspring-security-oauth2-resource-serverを使用し、リソースサーバーとしての設定を実装してください。
CORS設定とセキュリティに関する詳細
CORS(Cross-Origin Resource Sharing)は、フロントエンドとバックエンドが異なるドメインで運用される際、必須となる仕組みです。allowCredentials(true)を使用する際には以下の注意点があります。
allowCredentials(true)のリスクと対策
|
1 2 3 4 5 |
| 設定 | 影響 | 対応策 | |-------------|---------------------------|---------------------------------| | `true` | ユーザー認証情報を送信可能 | CSRFトークンを必ず有効化 | | `false` | クレデンシャルが無視される | 安全性向上、セッション管理で補う | |
⚠️ 重要:
allowCredentials(true)はCSRF対策が必須です。Spring SecurityではデフォルトでCsrfFilterが有効になっているため、allowCredentials(true)を使用する際にはこのフィルタが正しく動作していることを確認してください。
CORS設定の実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Configuration @EnableWebSecurity public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("https://your-frontend.com") // ⚠️ 実装時、ドメインを置き換えること .allowedMethods("GET", "POST") .allowCredentials(true) .maxAge(3600); } } |
セキュリティベストプラクティス
マイクロサービスのセキュリティ強化には、以下のポイントに注意することが重要です。
パスワードハッシュ化の注意点
パスワードは常にハッシュ化して保存する必要があります。BDK(bcrypt)などを使用し、暗号化されたパスワードをデータベースに保存してください。
CORS設定の最適化
CORS(Cross-Origin Resource Sharing)の設定が不十分だと、CSRFやXSS攻撃のリスクがあります。以下のように制限をかけるのが推奨されます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Configuration @EnableWebSecurity public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("https://your-frontend.com") .allowedMethods("GET", "POST") .allowCredentials(true) .maxAge(3600); } } |
この設定により、不正なオリジンからのリクエストを効果的にブロックできます。
まとめ
- マイクロサービスでは認証と認可の役割分離が必須です。
- Spring Securityはデフォルトで保護を開始し、
SecurityFilterChainで設定を行います。 - JWTトークンはリソースサーバー間でのユーザー情報共有に適しており、発行と検証手順を明確に理解することが重要です。
- OAuth2 Client/Resource Serverの導入により、外部認証サーバーとの連携が容易になります。
- パスワードハッシュ化やCORS設定など、セキュリティベストプラクティスを守ることが運用の基盤となります。
これらの手順と設計ポイントを取り入れることで、信頼性の高いSpring Bootマイクロサービス構築が可能になります。