「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>実装に入る前に
実装コードに入る前に、「なぜ scope に openid を書くと挙動が変わるのか」
「ログイン用途と外部APIアクセス用途でどう設計が違うのか」を整理しておくと
コードの意味が理解しやすくなります。

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の基礎・用語を整理したい方
認可の仕組みとして利用されるOAuth 2.0とは?用語・フローをわかりやすく解説
OIDCとID Tokenの仕組みを整理したい方
OpenID Connectとは?その仕組みと必要な知識とフローをまとめて解説
Authorization Code Grantの詳細とClient Credentials Grantとの使い分けはこちら。
サービス間通信の設計にも役立ちます。
Authorization Code GrantとClient Credentials Grantの違いと使い分け
AWS CognitoをIdPとして使う構成の全体像はこちら。
認証・認可の仕組みを完全理解|OAuth2.0・OpenID Connect・AWS Cognitoを初心者から実務レベルまで解説
まとめ: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


コメント