- 技術 💻
Keycloak入門|OIDCログインとJWT検証を最短で構築
Keycloakとは、ログイン画面・ユーザー管理・シングルサインオン(SSO)・トークン発行をまとめて引き受けるオープンソースの認証サーバー(IdP)です。 アプリは自分でパスワードを扱わず、OpenID Connect(OIDC)でKeycloakにログインを任せ、受け取ったアクセストークン(JWT)を検証するだけで済みます。
この記事では、2026年10月時点の Keycloak 26.7系(公式Getting Startedの記載は26.7.5)を前提に、用語の一覧 → PKCE付き認可コードフロー → 起動(開発・本番) → 管理画面とkcadmでの設定 → APIでのJWT検証を一気通貫で解説します。上位の解説記事では開発モード(start-dev)までのものが多いため、本番の起動オプション(DB・hostname・TLS・リバースプロキシ)と判断表まで載せました。
検証について:この記事の作成環境ではKeycloak本体(公式配布・コンテナイメージ)を入手できなかったため、起動・管理画面・kcadmの手順は公式ドキュメントに沿って記載し、未実行です。一方、JWT検証コードは、Keycloakと同じクレーム構造のトークンと JWKS をローカルで自作し、Python(PyJWT 2.15.1)と Node(jose 6.2.12)で実行して、期限切れ・aud違い・改ざんなど8パターンの結果を載せています。OAuth 2.0とOIDCの違いそのものは別記事で扱っているので、ここではKeycloakの設定に絞ります。
Keycloak入門の早見表
| やりたいこと | 方法(Keycloak 26.x) |
|---|---|
| 開発用に起動 | bin/kc.sh start-dev(HTTP 8080、DBは組み込み) |
| コンテナで開発用に起動 | docker run -p 8080:8080 -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:26.7.5 start-dev |
| 本番用に起動 | bin/kc.sh start --hostname=https://auth.example.com --db=postgres ...(HTTPS必須) |
| 最初の管理ユーザー | 環境変数 KC_BOOTSTRAP_ADMIN_USERNAME / KC_BOOTSTRAP_ADMIN_PASSWORD |
| 設定の入口(Discovery) | /realms/{realm}/.well-known/openid-configuration |
| ログイン(認可エンドポイント) | /realms/{realm}/protocol/openid-connect/auth |
| トークン取得 | /realms/{realm}/protocol/openid-connect/token |
| 公開鍵(JWKS) | /realms/{realm}/protocol/openid-connect/certs |
トークンの iss |
https://{hostname}/realms/{realm} |
| ロールの場所(JWT内) | Realmロール:realm_access.roles/Clientロール:resource_access.{client}.roles |
aud にAPI名を入れる |
Client Scope に Audience マッパーを追加 |
| SPAのクライアント設定 | Client authentication OFF(public)、Standard flow ON、PKCE S256 |
| CLIで設定 | bin/kcadm.sh config credentials ... → kcadm.sh create realms / clients / users |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Keycloak入門|OIDCログインとJWT検証を最短で構築」
Keycloakの用語一覧
Keycloakの設定は「Realm(区画)の中に、Client(アプリ)・User・Role を作り、Client Scope と Mapper でトークンの中身を決める」という構造です。
| 用語 | ひとことで | 入門で押さえる点 |
|---|---|---|
| Realm | ユーザーやアプリをまとめる独立した区画 | master は管理用。アプリ用には別のRealmを作る。iss に含まれる |
| Client | Keycloakにログインを任せるアプリ | client_id で識別。ブラウザだけで動くSPAは public、サーバー側アプリは confidential(クライアントシークレットあり) |
| User | ログインする人 | パスワード・属性・グループ・ロールを持つ |
| Group | ユーザーのまとまり | グループにロールを付けると所属ユーザーに継承される |
| Identity Provider / User Federation | 外部IdP連携/既存台帳(LDAPなど)連携 | ソーシャルログインや社内ディレクトリを使うとき |
| Realm Role | Realm全体で使うロール | JWTの realm_access.roles に入る |
| Client Role | 特定のClient用のロール | JWTの resource_access.{client_id}.roles に入る |
| Client Scope | トークンに含める情報のセット | profile・email・roles など。Clientに Default(常に付与)/Optional(scope 指定時のみ)で割り当てる |
| Mapper(Protocol Mapper) | トークンにクレームを追加・変換する部品 | ユーザー属性 → クレーム、Audience(aud の追加)など |
| Authentication Flow | ログインの手順の定義 | パスワード+ワンタイムパスワード(OTP)などを組み立てる |
PKCE付き認可コードフローとKeycloakの設定の対応
ブラウザで動くアプリ(SPA)やスマホアプリは、PKCE付きの認可コードフローを使います。 PKCE(ピクシー)は、ログイン開始時に作った秘密の値(code_verifier)を、トークン交換のときに提示させる仕組みで、認可コードの横取りを防ぎます。
sequenceDiagram
autonumber
actor U as ユーザー
participant W as order-web(public client)
participant K as Keycloak(realm: myrealm)
participant A as order-api(Resource Server)
U->>W: ログインをクリック
W->>W: code_verifier を生成し code_challenge = SHA256 を計算
W->>K: /realms/myrealm/protocol/openid-connect/auth<br/>client_id, redirect_uri, scope=openid, state, code_challenge(S256)
K->>U: ログイン画面(パスワード・MFA・外部IdP)
U->>K: 認証
K->>W: redirect_uri?code=...&state=...
W->>K: /protocol/openid-connect/token<br/>code + code_verifier
K->>W: access_token(JWT), id_token, refresh_token
W->>A: Authorization: Bearer access_token
A->>K: /protocol/openid-connect/certs(JWKSを取得しキャッシュ)
A->>A: 署名・iss・aud・exp・realm_access.roles を検証
A->>W: 200 OK(注文一覧)
| 図の番号 | Keycloak側で効いている設定 |
|---|---|
| 3 | Client の Valid redirect URIs(一致しないと Invalid parameter: redirect_uri)、PKCE Method = S256 |
| 4〜5 | Realm の Authentication Flow、Identity Provider、パスワードポリシー |
| 7 | Client の Client authentication(publicならシークレット不要)、Web origins(ブラウザから呼ぶときのCORS) |
| 8 | Realm の Tokens(アクセストークンの有効期間、既定5分)、Client Scope と Mapper(中身) |
| 10〜11 | Realm の Keys(署名鍵。kid で識別)、aud は Audience マッパー |
Keycloakを起動する(開発モードと本番モード)
start-dev は開発用の便利な既定値(HTTP有効・組み込みDB・キャッシュはローカル)で起動し、start は本番用にHTTPSとホスト名の設定を求めます。(以下は公式ドキュメントに沿った記載で、未実行です。)
開発モード
# ZIP版(展開したディレクトリで)
export KC_BOOTSTRAP_ADMIN_USERNAME=admin
export KC_BOOTSTRAP_ADMIN_PASSWORD=admin
bin/kc.sh start-dev
# コンテナ版
docker run -p 8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:26.7.5 start-dev
http://localhost:8080/admin/ にアクセスし、上の管理ユーザーでログインします。KC_BOOTSTRAP_ADMIN_* は最初の一時的な管理ユーザーを作るためのもので、ログイン後に正式な管理ユーザーを作り直すことが推奨されています。
本番モード(DB・hostname・TLS)
# 1) 使うDBなどを焼き込んでビルド(起動を速くする)
bin/kc.sh build --db=postgres --health-enabled=true --metrics-enabled=true
# 2) 起動
bin/kc.sh start --optimized \
--hostname=https://auth.example.com \
--https-certificate-file=/etc/keycloak/tls.crt \
--https-certificate-key-file=/etc/keycloak/tls.key \
--db-url-host=db.internal --db-url-database=keycloak \
--db-username=keycloak --db-password=change_me
同じ設定は conf/keycloak.conf に db-url-host=db.internal のように書くか、環境変数 KC_DB_URL_HOST=db.internal のように KC_ +大文字・アンダースコアで渡せます。
リバースプロキシでTLSを終端する構成では、証明書の2つのオプションの代わりに --proxy-headers=xforwarded --http-enabled=true を指定します。
| オプション | 意味 | ポイント |
|---|---|---|
--hostname |
外部に公開するURL | トークンの iss になる。APIの検証設定と完全に一致させる |
--https-certificate-file / -key-file |
TLS証明書と秘密鍵 | Keycloak自身でHTTPSを受ける場合 |
--proxy-headers |
xforwarded か forwarded |
プロキシが付けるヘッダーを信頼して、元のホスト・プロトコルを判断 |
--http-enabled |
HTTPを有効化 | TLSをプロキシで終端し、内部はHTTPで受けるとき |
--db |
DBの種類(postgres など) |
build 時に指定すると起動が速い |
--db-url-host / --db-username / --db-password |
DB接続先 | パスワードは環境変数やシークレット管理から渡す |
--health-enabled / --metrics-enabled |
ヘルスチェックとメトリクス | 管理用ポート(既定9000)の /health/ready などで公開 |
本番化の判断表
| 項目 | 開発(start-dev) |
本番(start) |
|---|---|---|
| 通信 | HTTP可 | HTTPS必須(自前TLSかプロキシ終端) |
| DB | 組み込みDB(開発用) | PostgreSQLなどの外部DB、バックアップ |
| ホスト名 | 自動(localhost) | --hostname を固定(iss が変わらないように) |
| 管理ユーザー | KC_BOOTSTRAP_ADMIN_* のまま |
正式な管理ユーザーを作り、一時ユーザーは削除 |
| 管理画面の公開 | そのまま | 管理画面のパスは社内からのみ到達できるようにする |
| 起動 | 毎回ビルド | build → start --optimized |
| 設定の管理 | 画面で手作業 | kcadm やRealmのエクスポート/インポートでコード化 |
管理画面での設定チェックリスト
order-web(ブラウザのアプリ)がログインし、order-api(API)を呼ぶ構成を作ります。
| # | 画面 | 設定 | 値の例 |
|---|---|---|---|
| 1 | Manage realms → Create realm | Realm名 | myrealm |
| 2 | Realm roles → Create role | ロール | order-reader |
| 3 | Users → Create new user | ユーザー | alice、Email verified ON |
| 4 | Users → alice → Credentials | パスワード | Temporary を OFF(ONだと初回に変更を求められる) |
| 5 | Users → alice → Role mapping | ロールを付与 | order-reader |
| 6 | Clients → Create client | Client ID・種類 | order-web、OpenID Connect |
| 7 | 同上 Capability config | 認証方式とフロー | Client authentication OFF、Standard flow ON、Direct access grants OFF |
| 8 | 同上 Login settings | URL | Valid redirect URIs http://localhost:5173/*、Valid post logout redirect URIs、Web origins http://localhost:5173 |
| 9 | Clients → order-web → Advanced | PKCE | Proof Key for Code Exchange Code Challenge Method S256 |
| 10 | Clients → Create client | API用のClient | order-api(aud の値として使う。ログイン用のフローはすべてOFF) |
| 11 | Clients → order-web → Client scopes → order-web-dedicated → Add mapper | Audience | Included Client Audience order-api、Add to access token ON |
| 12 | Realm settings → Tokens | 有効期間 | Access Token Lifespan(既定5分)を必要に応じて調整 |
11のAudienceマッパーを忘れると、アクセストークンの aud にAPI名が入らず、API側の検証で aud 違いになります。 既定では、ロールの設定によって aud が account だけになることがあります。
kcadm(管理CLI)で同じ設定を作る
画面の操作は、kcadm.sh でコマンドにできます(未実行。公式Admin CLIガイドの書式に沿って記載)。
KC=bin/kcadm.sh
$KC config credentials --server http://localhost:8080 --realm master --user admin --password admin
$KC create realms -s realm=myrealm -s enabled=true
$KC create roles -r myrealm -s name=order-reader
$KC create users -r myrealm -s username=alice -s enabled=true -s email=alice@example.com -s emailVerified=true
$KC set-password -r myrealm --username alice --new-password 'ChangeMe-123'
$KC add-roles -r myrealm --uusername alice --rolename order-reader
$KC create clients -r myrealm \
-s clientId=order-web -s publicClient=true \
-s standardFlowEnabled=true -s directAccessGrantsEnabled=false \
-s 'redirectUris=["http://localhost:5173/*"]' \
-s 'webOrigins=["http://localhost:5173"]' \
-s 'attributes."pkce.code.challenge.method"=S256'
$KC create clients -r myrealm -s clientId=order-api -s publicClient=false \
-s standardFlowEnabled=false -s directAccessGrantsEnabled=false
# Audienceマッパー(order-web の id を取得してから追加)
WEB_ID=$($KC get clients -r myrealm -q clientId=order-web --fields id --format csv --noquotes)
$KC create clients/$WEB_ID/protocol-mappers/models -r myrealm \
-s name=audience-order-api -s protocol=openid-connect \
-s protocolMapper=oidc-audience-mapper \
-s 'config."included.client.audience"=order-api' \
-s 'config."access.token.claim"=true' -s 'config."id.token.claim"=false'
設定をコマンドにしておくと、開発・検証・本番で同じRealmを再現できます。 Realm全体は管理画面の Realm settings → Action → Partial export や、kc.sh export / kc.sh import でも移せます。
アクセストークン(JWT)をAPIで検証する
APIは、受け取ったJWTを「JWKSの公開鍵で署名確認 → iss・aud・exp を確認 → ロールで認可」の順に検証します。Keycloakに毎回問い合わせる必要はなく、公開鍵をキャッシュして手元で検証できます。
| 確認項目 | 期待する値 |
|---|---|
| 署名 | ヘッダーの kid に対応するJWKSの公開鍵で検証成功(改ざんの検出) |
alg |
RS256 に固定(想定外のアルゴリズムを受け付けない) |
iss |
https://{hostname}/realms/myrealm(別Realm・別IdPのトークンを区別) |
aud |
order-api(別アプリ向けのトークンを区別) |
exp |
現在時刻より後(数十秒の猶予) |
| ロール | realm_access.roles に必要なロール |
検証用のトークンとJWKSを作る(Keycloakの代わり)
本物のKeycloakが出すトークンと同じクレーム構造(iss・aud・exp・azp・realm_access など)を、手元のRSA鍵で作りました。JWKSは python -m http.server 7860 で /realms/myrealm/protocol/openid-connect/certs として配信しています。
cryptography で作ったRSA 2048ビット鍵の公開鍵をJWKS(kid・use: sig・alg: RS256)にし、秘密鍵で次のクレームを持つトークンをRS256で署名しています:exp(5分後)・iat・jti・iss(http://localhost:8080/realms/myrealm)・aud(order-api)・sub・typ: Bearer・azp: order-web・scope・realm_access.roles(order-reader など)・resource_access・preferred_username。
この正しいトークン(valid)をもとに、exp を過去にした「期限切れ」、aud を account にした「aud違い」、iss を別Realmにした「iss違い」、ロールを外した「ロールなし」を作りました。さらに、①ペイロードにロール order-admin を書き足して署名はそのままにした「改ざん」、②HS256で作った「アルゴリズム違い」、③別の鍵・未知の kid(rotated-key-2)で署名した「鍵が見つからない」の3つを加え、計8パターンを用意しました。
Python(PyJWT)での検証コード
# verify.py pip install "pyjwt[crypto]" (確認:PyJWT 2.15.1 / cryptography 50.0.2 / Python 3.11)
import jwt
from jwt import PyJWKClient
ISSUER = "http://localhost:8080/realms/myrealm"
AUDIENCE = "order-api"
JWKS_URL = "http://127.0.0.1:7860/realms/myrealm/protocol/openid-connect/certs"
# 本物のKeycloakなら f"{ISSUER}/protocol/openid-connect/certs"
jwks_client = PyJWKClient(JWKS_URL, cache_keys=True, lifespan=300)
def verify_access_token(token: str, required_role: str | None = None) -> dict:
signing_key = jwks_client.get_signing_key_from_jwt(token) # ヘッダーのkidで公開鍵を選ぶ
claims = jwt.decode(
token,
signing_key.key,
algorithms=["RS256"], # 受け付けるアルゴリズムを固定する
audience=AUDIENCE,
issuer=ISSUER,
leeway=30, # 時計のずれを30秒まで許容
options={"require": ["exp", "iat", "iss", "aud", "sub"]},
)
if required_role:
roles = claims.get("realm_access", {}).get("roles", [])
if required_role not in roles:
raise PermissionError(f"role '{required_role}' がありません: {roles}")
return claims
# 確認用:tokens.json の8つのトークンで verify_access_token(t, required_role="order-reader") を呼び、
# 成功なら sub・ユーザー名・ロール、失敗なら例外名とメッセージを表示
実行結果:
valid OK sub=3f6c1c1e-0000-4000-8000-000000000001 user=alice roles=['order-reader', 'default-roles-myrealm']
expired NG ExpiredSignatureError: Signature has expired
wrong_aud NG InvalidAudienceError: Audience doesn't match
wrong_iss NG InvalidIssuerError: Invalid issuer
no_role NG PermissionError: role 'order-reader' がありません: ['default-roles-myrealm']
tampered NG InvalidSignatureError: Signature verification failed
hs256_forged NG InvalidAlgorithmError: The specified alg value is not allowed
unknown_kid NG PyJWKClientError: Unable to find a signing key that matches: "rotated-key-2"
8パターン中、正しいトークンだけが通り、残り7つはそれぞれ別の例外で止まりました。 例外の種類で原因がわかるので、ログには例外名を残しておくと調査が速くなります。
つまずきやすい書き方(直す前と後)
# 直す前:algorithms を省略
jwt.decode(token, key)
# → DecodeError: It is required that you pass in a value for the "algorithms" argument when calling decode().
# 直す前:トークンに aud があるのに audience を渡していない
jwt.decode(token, key, algorithms=["RS256"])
# → InvalidAudienceError: Invalid audience
# 直した後
jwt.decode(token, key, algorithms=["RS256"], audience="order-api", issuer=ISSUER)
(上の2つのエラー文は、同じトークンで実際に出力されたものです。)
PyJWTは aud を含むトークンに audience 指定がないと検証を通しません。 options={"verify_aud": False} で回避するのではなく、Keycloak側でAudienceマッパーを設定し、APIで audience を指定するのが正しい直し方です。
Node(jose)での検証コード
// verify.mjs npm install jose (確認:jose 6.2.12 / Node 22)
import { createRemoteJWKSet, jwtVerify } from 'jose';
const ISSUER = 'http://localhost:8080/realms/myrealm';
const JWKS = createRemoteJWKSet(
new URL('http://127.0.0.1:7860/realms/myrealm/protocol/openid-connect/certs') // 本物は `${ISSUER}/protocol/openid-connect/certs`
);
export async function verifyAccessToken(token, requiredRole) {
const { payload } = await jwtVerify(token, JWKS, {
issuer: ISSUER,
audience: 'order-api',
algorithms: ['RS256'],
clockTolerance: 30,
});
const roles = payload.realm_access?.roles ?? [];
if (requiredRole && !roles.includes(requiredRole)) throw new Error(`role ${requiredRole} がありません`);
return payload;
}
// 確認用:Pythonと同じ8つのトークンで verifyAccessToken(t, 'order-reader') を呼び、結果を表示
実行結果:
valid OK alice
expired NG ERR_JWT_EXPIRED - "exp" claim timestamp check failed
wrong_aud NG ERR_JWT_CLAIM_VALIDATION_FAILED - unexpected "aud" claim value
wrong_iss NG ERR_JWT_CLAIM_VALIDATION_FAILED - unexpected "iss" claim value
no_role NG Error - role order-reader がありません
tampered NG ERR_JWS_SIGNATURE_VERIFICATION_FAILED - signature verification failed
hs256_forged NG ERR_JOSE_ALG_NOT_ALLOWED - "alg" (Algorithm) Header Parameter value not allowed
unknown_kid NG ERR_JWKS_NO_MATCHING_KEY - no applicable key found in the JSON Web Key Set
createRemoteJWKSet は鍵をキャッシュし、未知の kid が来たときだけ取り直します。 Keycloakで鍵をローテーションしても、APIの再起動は不要です。Expressなどでは、Authorization: Bearer ヘッダーから取り出したトークンを verifyAccessToken() に渡すミドルウェアにします。
Spring Security(Resource Server)の設定例
Spring Bootでは spring-boot-starter-oauth2-resource-server を使います(この記事の環境ではMaven Centralに接続できないため未実行)。
# application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/realms/myrealm # 起動時にDiscoveryからJWKSの場所を取得
audiences: order-api
// import は org.springframework.security.* と java.util.* (省略)
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain api(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/orders/**").hasRole("order-reader")
.anyRequest().authenticated())
.oauth2ResourceServer(oauth -> oauth
.jwt(jwt -> jwt.jwtAuthenticationConverter(keycloakRoles())));
return http.build();
}
// realm_access.roles を ROLE_xxx に変換する(既定では scope クレームしか見ない)
private JwtAuthenticationConverter keycloakRoles() {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(jwt -> {
Map<String, Object> realm = jwt.getClaim("realm_access");
if (realm == null) return List.of();
@SuppressWarnings("unchecked")
Collection<String> roles = (Collection<String>) realm.getOrDefault("roles", List.of());
return roles.stream()
.map(r -> (GrantedAuthority) new SimpleGrantedAuthority("ROLE_" + r))
.toList();
});
return converter;
}
}
Spring Securityは既定で scope クレームから権限(SCOPE_xxx)を作るため、Keycloakのロールを使うには変換が必要です。
よくあるエラーと対処
| 症状・メッセージ | 原因 | 対処 |
|---|---|---|
ログイン画面に Invalid parameter: redirect_uri |
Valid redirect URIs と一致しない | 末尾の /*、ポート、http/https まで合わせる |
API で aud 違い(PyJWT:Audience doesn't match) |
Audienceマッパー未設定で aud が account など |
Client Scope に Audience マッパーを追加 |
API で iss 違い(Invalid issuer) |
--hostname とAPIの設定が違う/プロキシ経由で別URLになっている |
iss を固定し、APIの issuer と完全一致させる |
Signature has expired が頻発 |
アクセストークンの有効期間(既定5分)切れ | リフレッシュトークンで更新。サーバー間の時刻同期と leeway |
鍵が見つからない(Unable to find a signing key) |
鍵のローテーション後、または別Realmのトークン | JWKSのキャッシュ更新を確認、Realmを確認 |
| ブラウザでトークン取得がCORSエラー | Web origins 未設定 | アプリのオリジンを Web origins に追加 |
| PKCE関連のエラーでトークン交換できない | PKCE必須なのに code_challenge を送っていない、code_verifier 不一致 |
クライアントライブラリでPKCEを有効化 |
| 本番起動でHTTPSの設定を求められて起動しない | start はHTTPSが前提 |
証明書を指定するか、プロキシ終端なら --http-enabled=true と --proxy-headers |
よくある質問
Q. アクセストークンの検証はKeycloakに毎回問い合わせる必要がありますか?
A. いいえ。JWKSの公開鍵をキャッシュして、API側で署名と iss・aud・exp を検証できます。 即時の無効化(ログアウト直後に使えなくする)が必要な場合は、アクセストークンの有効期間を短くするか、トークンイントロスペクション(Keycloakへの問い合わせ)を併用します。
Q. SPAのクライアントは public と confidential のどちらにしますか? A. ブラウザだけで動くSPAは public(Client authentication OFF)+PKCE にします。ブラウザにシークレットを置いても隠せないためです。サーバー側でトークンを扱う構成(BFF)なら confidential にできます。
Q. Realmロールとクライアントロールはどう使い分けますか?
A. 複数のアプリで共通の役割(例:order-reader)は Realmロール、特定のAPIだけの細かい権限は クライアントロール が整理しやすいです。JWTでは前者が realm_access.roles、後者が resource_access.{client}.roles に入ります。
まとめ
- KeycloakはログインとトークンをまとめるIdP。アプリ用には
masterではなく専用のRealmを作る - SPAは public client + Standard flow + PKCE(S256)。redirect URIs と Web origins を正確に
- APIに渡すトークンの
audは Audience マッパーで設定し、API側でaudienceを指定して検証する - JWT検証は JWKS の公開鍵で署名、
alg固定、iss・aud・exp・ロールの確認。8パターン中、正しいトークンだけが通ることを確認した - 本番は
build→start --optimized、外部DB・HTTPS・固定hostname。プロキシ終端なら--proxy-headers - 設定は kcadm やエクスポートでコード化して、環境ごとに同じRealmを再現する
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Keycloak入門|OIDCログインとJWT検証を最短で構築」
株式会社RJCでは、Keycloakを使った認証基盤の仕組みを仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。