「OAuth2.0 と OpenID Connect は何が違うのか」「Spring Security がどこまで自動でやってくれるのか」——この2点で混乱している方は多いのではないでしょうか。
本記事では、Spring Boot + Spring Security を使った実装を通じて、OAuth2.0(認可フレームワーク)と OpenID Connect(認証プロトコル)それぞれの役割を明確に区別しながら解説します。あわせて、AWS Cognito を IdP として利用するための Tips もご紹介します。
対象読者は Spring Boot の基礎を理解しており、認証・認可の仕組みを深く学びたいバックエンドエンジニアです。
全体構成図で把握する

上の図は、Spring Boot アプリケーションが OAuth2.0 / OpenID Connect を利用する際の全体像です。登場人物を整理すると次のようになります。
- ブラウザ(エンドユーザー):アプリにアクセスする主体
- Spring Boot Application:OAuth2 Client と Resource Server の両役割を担う
- Authorization Server(IdP):認可コード・Access Token・ID Token を発行する
- OIDC 専用エンドポイント:UserInfo エンドポイントおよびディスカバリーエンドポイントを提供(OpenID Connect の追加機能)
図の下部にある「プロトコル役割の整理」がこの記事の核心です。OAuth2.0 は「認可コードフロー・Access Token・scope による権限管理」を担い、OpenID Connect はその上に「ID Token によるユーザー認証・UserInfo エンドポイント」を追加します。
OAuth2.0 と OpenID Connect の違いを整理する

最も重要な前提として、OAuth2.0 は「認可(Authorization)」のフレームワークであり、OpenID Connect は「認証(Authentication)」のプロトコルです。OAuth2.0 単体では「このユーザーが誰なのか」を証明する手段がありません。
| 項目 | OAuth2.0 | OpenID Connect |
|---|---|---|
| 目的 | 認可(何をさせてよいか) | 認証(誰であるか) |
| 主なトークン | Access Token | ID Token(JWT) |
| 有効化条件 | 任意の scope | scope に openid を含める |
| Spring クラス | OAuth2User / JwtAuthenticationToken | OidcUser / OidcIdToken |
| エンドポイント | /oauth2/authorize, /oauth2/token | /userinfo, /.well-known/openid-configuration |
ポイント:scope に openid を追加するだけで、認可サーバーは ID Token を発行し、Spring Security は自動的に OIDC モードで動作します。既存の OAuth2 設定に1単語追加するだけで認証機能が有効化されるのが OIDC の特徴です。
プロジェクトのセットアップ
Spring Initializr で以下の依存関係を追加します。OAuth2 Client は認可コードフローとログイン処理(OIDC 含む)を担い、OAuth2 Resource Server は JWT 検証による API 保護を担います。
<!-- pom.xml -->
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Security (OAuth2 Client + Resource Server 両方含む)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
</dependencies>application.yml の設定(OAuth2 Client + OIDC)
Spring Boot の自動設定を最大限に活用します。issuer-uri を指定すると、Spring Security がディスカバリーエンドポイント(/.well-known/openid-configuration)を参照し、認可エンドポイント・トークンエンドポイント・JWKS URI を自動取得します。これはOpenID Connect のディスカバリー機能です。
spring:
security:
oauth2:
# --- OAuth2 Client (ログイン + OIDC) の設定 ---
client:
registration:
my-idp: # 任意のクライアント登録ID
client-id: your-client-id
client-secret: your-client-secret
# scope に openid を含めることで OIDC が有効化される
# profile, email は OIDC の追加クレーム取得用
scope:
- openid # 【OIDC】 ID Token 発行のトリガー
- profile # 【OIDC】 name, picture 等のクレーム
- email # 【OIDC】 email クレーム
authorization-grant-type: authorization_code # 【OAuth2.0】
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
provider:
my-idp:
# issuer-uri を指定するだけで全エンドポイントが自動設定される
# これは OIDC ディスカバリーの機能
issuer-uri: https://your-idp.example.com
# --- Resource Server (API 保護 + JWT 検証) の設定 ---
resourceserver:
jwt:
# 【OAuth2.0】 JWK Set URI で署名検証用公開鍵を取得
jwk-set-uri: https://your-idp.example.com/.well-known/jwks.json
# issuer-uri でも代替可能(自動で jwks_uri を取得)
# issuer-uri: https://your-idp.example.comSecurityFilterChain の設定
Spring Security 6 以降は SecurityFilterChain を Bean として定義する方式が標準です。oauth2Login() が OAuth2 Client(認可コードフロー + OIDC)を有効化し、oauth2ResourceServer() が Resource Server(JWT 検証)を有効化します。
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/public/**").permitAll() // 公開ページ
.anyRequest().authenticated() // それ以外は認証必須
)
/*
* 【OAuth2.0 + OIDC】 oauth2Login() を有効化することで以下が自動設定される:
* - OAuth2LoginAuthenticationFilter(認可コード受け取り)
* - AuthorizationRequestRedirectFilter(認可サーバーへのリダイレクト)
* - OidcUserService(ID Token の検証 + UserInfo 取得)<- OIDC 専用
*/
.oauth2Login(oauth2 -> oauth2
.defaultSuccessUrl("/dashboard", true)
)
/*
* 【OAuth2.0】 oauth2ResourceServer() を有効化することで以下が自動設定される:
* - BearerTokenAuthenticationFilter(Authorization ヘッダーから JWT 取り出し)
* - JwtAuthenticationProvider(JwtDecoder で JWT を検証)
* - JwtAuthenticationConverter(JWT クレームを権限に変換)
*/
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(Customizer.withDefaults())
);
return http.build();
}
}oauth2Login() と oauth2ResourceServer() の使い分け:前者はブラウザベースのログインフロー(セッション管理・リダイレクト)を担い、後者は REST API へのリクエストに付与された Bearer トークンの検証を担います。Web アプリと API の両方を提供する場合は、2つの SecurityFilterChain を定義して役割を分けるか、1つの FilterChain に両方を共存させます。
認証フロー詳細(Authorization Code + OIDC)

左のフロー(①〜⑥)が OAuth2 Client のログインフロー、右のフローが Resource Server の JWT 検証フローです。それぞれの処理をコードレベルで確認しましょう。
- ①アクセス:未認証ユーザーが
/protectedにアクセス - ②リダイレクト:
AuthorizationRequestRedirectFilterが認可サーバーへリダイレクト(OAuth2.0) - ③認可コード返却:ユーザーが認証・同意後、コールバック URL に認可コードが届く(OAuth2.0)
- ④トークン取得:
OAuth2LoginAuthenticationFilterがサーバー間通信でトークンを取得。scope にopenidがあれば ID Token も返却される(OAuth2.0 + OIDC) - ⑤ID Token 検証 + UserInfo 取得:
OidcUserServiceが ID Token の署名・クレームを検証し、UserInfo エンドポイントからプロフィールを取得。OidcUserを生成(OIDC 専用処理) - ⑥SecurityContext 保存:認証済み
OidcUserを SecurityContext に格納。以降のリクエストはセッションで認証状態を維持
コントローラーでユーザー情報を取得する
認証完了後は @AuthenticationPrincipal アノテーションで OidcUser を取得できます。OidcUser は ID Token のクレームと UserInfo エンドポイントの情報を統合したオブジェクトです。これはOpenID Connect の機能です。
@RestController
public class UserController {
/**
* 【OIDC】 OidcUser はID TokenとUserInfoエンドポイントの情報を統合したオブジェクト
* scope=openid を指定している場合のみ OidcUser として取得可能
*/
@GetMapping("/me")
public Map<String, Object> currentUser(
@AuthenticationPrincipal OidcUser oidcUser) {
return Map.of(
// 【OIDC】 ID Token のクレーム(sub = ユーザーの一意ID)
"sub", oidcUser.getSubject(),
"email", oidcUser.getEmail(),
"name", oidcUser.getFullName(),
// 【OIDC】 ID Token 全体を取得
"idToken", oidcUser.getIdToken().getTokenValue(),
// 【OAuth2.0】 権限情報
"authorities", oidcUser.getAuthorities()
);
}
/**
* 【OAuth2.0】 Resource Server として動作するエンドポイント
* Authorization: Bearer <JWT> ヘッダーで呼び出す
* JwtAuthenticationToken はAccess TokenのJWT情報を保持
*/
@GetMapping("/api/resource")
public Map<String, Object> protectedResource(
@AuthenticationPrincipal Jwt jwt) {
return Map.of(
// 【OAuth2.0】 JWT クレーム(Access Token のペイロード)
"sub", jwt.getSubject(),
"scope", jwt.getClaimAsStringList("scope"),
"issuer", jwt.getIssuer()
);
}
}Resource Server の JWT 検証をカスタマイズする
Resource Server の JWT 検証(OAuth2.0 の機能)では、デフォルトで署名・有効期限(exp)・発行者(iss)・受信者(aud)が検証されます。aud クレームの検証を追加する場合は JwtDecoder をカスタム Bean として定義します。
@Configuration
public class JwtConfig {
/**
* 【OAuth2.0】 JwtDecoder をカスタマイズして aud クレームを検証
* spring.security.oauth2.resourceserver.jwt.issuer-uri を参照して
* JWKS URI を自動取得するため、issuer-uri の設定が必要
*/
@Bean
public JwtDecoder jwtDecoder(
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}") String issuerUri) {
NimbusJwtDecoder decoder = JwtDecoders.fromIssuerLocation(issuerUri);
// カスタムバリデーター: aud クレームに my-api が含まれることを確認
OAuth2TokenValidator<Jwt> audienceValidator =
jwt -> jwt.getAudience().contains("my-api")
? OAuth2TokenValidatorResult.success()
: OAuth2TokenValidatorResult.failure(
new OAuth2Error("invalid_token", "Invalid audience", null));
// デフォルトの検証(iss, exp)にカスタム検証を追加
OAuth2TokenValidator<Jwt> combinedValidator =
new DelegatingOAuth2TokenValidator<>(
JwtValidators.createDefaultWithIssuer(issuerUri),
audienceValidator
);
decoder.setJwtValidator(combinedValidator);
return decoder;
}
/**
* 【OAuth2.0】 JWT クレームから権限(GrantedAuthority)へのマッピングをカスタマイズ
* デフォルトは scope クレームを SCOPE_ プレフィックス付きで権限化する
*/
@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtGrantedAuthoritiesConverter converter = new JwtGrantedAuthoritiesConverter();
converter.setAuthorityPrefix("ROLE_"); // プレフィックスを変更
converter.setAuthoritiesClaimName("roles"); // クレーム名を変更(デフォルトは scope)
JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
jwtConverter.setJwtGrantedAuthoritiesConverter(converter);
return jwtConverter;
}
}OIDC の UserInfo エンドポイントと OidcUser の仕組み
Spring Security が OIDC 対応の IdP に接続する際、以下の処理を自動で行います。これらはすべてOpenID Connect の機能です。
- ID Token の検証:
OidcIdTokenDecoderFactoryが ID Token(JWT)の署名・nonce・iss・aud を検証 - UserInfo エンドポイント呼び出し:
OidcUserServiceが Access Token を使って/userinfoを呼び出し、追加クレームを取得 - OidcUser の生成:ID Token のクレームと UserInfo レスポンスをマージして
DefaultOidcUserを生成
UserInfo の呼び出しをカスタマイズする場合は OidcUserService を Bean として定義します。
@Configuration
public class OidcConfig {
/**
* 【OIDC専用】 OidcUserService をカスタマイズ
* デフォルトでは scope=openid 時に UserInfo エンドポイントを自動呼び出し
* 追加で取得したいスコープ(groups, custom_claim 等)を指定可能
*/
@Bean
public OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() {
OidcUserService delegate = new OidcUserService();
// UserInfo エンドポイントから追加で取得するスコープを指定
delegate.setAccessibleScopes(Set.of("profile", "email", "groups"));
return userRequest -> {
// 標準の OidcUser 生成処理を実行
OidcUser oidcUser = delegate.loadUser(userRequest);
// 独自クレームからロールを生成する例
Set<GrantedAuthority> authorities = new HashSet<>(oidcUser.getAuthorities());
List<String> groups = oidcUser.getClaimAsStringList("groups");
if (groups != null) {
groups.stream()
.map(g -> new SimpleGrantedAuthority("ROLE_" + g.toUpperCase()))
.forEach(authorities::add);
}
return new DefaultOidcUser(
authorities,
oidcUser.getIdToken(),
oidcUser.getUserInfo()
);
};
}
}AWS Cognito を IdP として利用する Tips
AWS Cognito は OAuth2.0 / OpenID Connect に対応したマネージドサービスです。前述の Authorization Server と OIDC エンドポイントをすべて提供するため、Spring Boot アプリの設定変更はほぼ不要です。
spring:
security:
oauth2:
client:
registration:
cognito:
client-id: YOUR_COGNITO_APP_CLIENT_ID
client-secret: YOUR_COGNITO_APP_CLIENT_SECRET
scope:
- openid
- email
- profile
provider:
cognito:
# リージョンと User Pool ID を変更するだけ
issuer-uri: https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXX
resourceserver:
jwt:
jwk-set-uri: https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXX/.well-known/jwks.jsonCognito 特有の注意点を以下にまとめます。
- userNameAttributeName の設定:Cognito は UserInfo レスポンスのユーザー名属性が
cognito:usernameまたはusernameになります。provider.cognito.user-name-attribute: usernameを設定しないと認証失敗することがあります。 - RP-Initiated Logout 非対応:Cognito は OpenID Connect の RP-Initiated Logout 仕様を完全には実装していません。ログアウト時には
https://DOMAIN.auth.ap-northeast-1.amazoncognito.com/logoutへのカスタムリダイレクトが必要です。 - aud クレームの違い:Cognito が発行する Access Token の
audクレームは User Pool のclient_idではなく Cognito 独自の値になることがあります。JwtDecoder のバリデーターを調整する必要があります。 - issuer-uri 一つで完結:
issuer-uriを指定するだけで、認可エンドポイント・トークンエンドポイント・JWKS URI・UserInfo エンドポイントがすべて自動設定されます。
Cognito の OIDC ディスカバリーを確認する:ブラウザで https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/openid-configuration にアクセスすると、Cognito が提供する全エンドポイントの一覧を JSON 形式で確認できます。Spring Security はこの URL を自動取得して設定に使用します。
まとめ:OAuth2.0 と OIDC の役割を Spring Security のコードで見る
| 処理 | Spring Security クラス | プロトコル |
|---|---|---|
| 認可サーバーへのリダイレクト | AuthorizationRequestRedirectFilter | OAuth2.0 |
| 認可コードの受け取り | OAuth2LoginAuthenticationFilter | OAuth2.0 |
| トークンエンドポイント呼び出し | DefaultAuthorizationCodeTokenResponseClient | OAuth2.0 |
| ID Token の検証 | OidcIdTokenDecoderFactory | OIDC(専用) |
| UserInfo エンドポイント呼び出し | OidcUserService | OIDC(専用) |
| ユーザー情報の保持 | OidcUser / DefaultOidcUser | OIDC(専用) |
| Bearer トークンの抽出 | BearerTokenAuthenticationFilter | OAuth2.0 |
| JWT の署名・クレーム検証 | JwtDecoder / NimbusJwtDecoder | OAuth2.0 |
| JWT からの権限マッピング | JwtAuthenticationConverter | OAuth2.0 |
Spring Security は OAuth2.0 と OpenID Connect を深く統合しており、設定ベースで多くの処理を自動化します。重要なのは「oauth2Login() で OIDC ログインフローが有効化され、oauth2ResourceServer() で JWT 検証による API 保護が有効化される」という役割の分担を理解することです。scope に openid を含めた瞬間から、Spring Security は自動的に OIDC モードに切り替わり ID Token の検証と OidcUser の生成を行います。
参考リソース
- Spring Security 公式ドキュメント – OAuth 2.0 Login
- Spring Security 公式ドキュメント – OAuth 2.0 Resource Server JWT
- Spring Security 公式ドキュメント – OAuth2 全体
- Spring 公式チュートリアル – Spring Boot and OAuth2
- Baeldung – Spring Security and OpenID Connect
- Baeldung – Authenticating with Amazon Cognito Using Spring Security
- rieckpil – Thymeleaf OAuth2 Login with Spring Security and AWS Cognito

コメント