.NET Aspire Keycloak 統合 (プレビュー)
含まれるもの:ホスティング統合 と Client 統合 があります。
Keycloak は、最新のアプリケーションとサービスを目的としたオープンソースの ID およびアクセス管理ソリューションです。
.NET Aspire
Keycloak 統合を使用すると、既存の Keycloak インスタンスに接続したり、quay.io/keycloak/keycloak
コンテナー イメージを使用して .NET から新しいインスタンスを作成したりできます。
ホスティング統合
.NET Aspire Keycloak ホスティング統合では、server が KeycloakResource の種類としてモデル化されます。 これらの型と API にアクセスするには、📦Aspire.Hosting.Keycloak NuGet パッケージを アプリ ホスト プロジェクトに追加します。
dotnet add package Aspire.Hosting.Keycloak --prerelease
詳細については、「dotnet パッケージ の追加」または「.NET アプリケーションでのパッケージの依存関係の管理」を参照してください。
リソース Keycloak を追加する
アプリ ホスト プロジェクトで、AddKeycloak を呼び出して、Keycloak リソース ビルダーを追加して返します。 返されたリソース ビルダーへの呼び出しをチェーンして、Keycloakを構成します。
var builder = DistributedApplication.CreateBuilder(args);
var keycloak = builder.AddKeycloak("keycloak", 8080);
var apiService = builder.AddProject<Projects.Keycloak_ApiService>("apiservice")
.WithReference(keycloak)
.WaitFor(keycloak);
builder.AddProject<Projects.Keycloak_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(keycloak)
.WithReference(apiService)
.WaitFor(apiService);
// After adding all resources, run the app...
ヒント
ローカル開発では、Keycloak リソースの安定したポートを使用します (前の例8080
)。 任意のポートを指定できますが、アプリ ホストの有効期間を超えて OIDC トークン (機関 URL を含むポートを含む) を保持するブラウザー Cookie の問題を回避するには、安定している必要があります。
.NET
.NET Aspire 前の例で示したように、quay.io/keycloak/keycloak
イメージでコンテナー イメージをアプリ ホストに追加すると、ローカル コンピューターに新しい Keycloak インスタンスが作成されます。
Keycloak リソースには、既定の資格情報が含まれています。
-
KEYCLOAK_ADMIN
:admin
の値です。 -
KEYCLOAK_ADMIN_PASSWORD
: CreateDefaultPasswordParameter メソッドを使用して生成されたランダムpassword
。
アプリ ホストを実行すると、パスワードはアプリ ホストのシークレット ストアに格納されます。 次のように、Parameters
セクションに追加されます。
{
"Parameters:keycloak-password": "<THE_GENERATED_PASSWORD>"
}
パラメーターの名前は keycloak-password
ですが、実際にはリソース名を -password
サフィックスで書式設定するだけです。 詳細については、「
WithReference メソッドは、keycloak
という名前の ExampleProject
で接続を構成し、WaitFor は、keycloak
リソースの準備ができるまで依存サービスを開始しないようにアプリ ホストに指示します。
ヒント
既存の Keycloak インスタンスに接続する場合は、代わりに AddConnectionString 呼び出します。 詳細については、「既存のリソースを参照する」を参照してください。
データ ボリューム Keycloak リソースを追加する
Keycloak リソースにデータ ボリュームを追加するには、Keycloak リソースで WithDataVolume メソッドを呼び出します。
var keycloak = builder.AddKeycloak("keycloak", 8080)
.WithDataVolume();
var apiService = builder.AddProject<Projects.Keycloak_ApiService>("apiservice")
.WithReference(keycloak)
.WaitFor(keycloak);
builder.AddProject<Projects.Keycloak_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(keycloak)
.WithReference(apiService)
.WaitFor(apiService);
// After adding all resources, run the app...
データ ボリュームは、Keycloak データをコンテナーのライフサイクル外に保持するために使用されます。 データ ボリュームは、Keycloak コンテナー内の /opt/keycloak/data
パスにマウントされ、name
パラメーターが指定されていない場合、名前はランダムに生成されます。 データボリュームに関する詳細や、それがバインドマウントよりも優先される理由については、Docker ドキュメント「ボリューム」を参照してください。
警告
管理者の資格情報は、データ ボリュームに格納されます。 データ ボリュームを使用していて、資格情報が変更された場合、ボリュームを削除するまでは機能しません。
データのバインドマウントを使用して Keycloak リソースを追加する
Keycloak リソースにデータ バインド マウントを追加するには、WithDataBindMount メソッドを呼び出します。
var keycloak = builder.AddKeycloak("keycloak", 8080)
.WithDataBindMount(@"C:\Keycloak\Data");
var apiService = builder.AddProject<Projects.Keycloak_ApiService>("apiservice")
.WithReference(keycloak)
.WaitFor(keycloak);
builder.AddProject<Projects.Keycloak_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(keycloak)
.WithReference(apiService)
.WaitFor(apiService);
// After adding all resources, run the app...
大事な
データ バインド マウント、パフォーマンス、移植性、およびセキュリティが向上し、運用環境に適した ボリュームと比較して機能が制限されています。 ただし、バインド マウントを使用すると、ホスト システム上のファイルに直接アクセスして変更できるため、リアルタイムの変更が必要な開発とテストに最適です。
データ バインド マウントは、ホスト マシンのファイルシステムに依存して、コンテナーの再起動間に Keycloak データを保持します。 データ バインド マウントは、Keycloak コンテナー内のホスト コンピューター上の Windows 上の C:\Keycloak\Data
(または Unixの /Keycloak/Data
) パスにマウントされます。 データバインドマウントの詳細については、Docker ドキュメントの「バインドマウント」を参照してください。
Keycloak リソースをパラメーター付きで追加する
コンテナー イメージで使用される管理者ユーザー名とパスワードを明示的に指定する場合は、これらの資格情報をパラメーターとして指定できます。 次の代替例を考えてみましょう。
var builder = DistributedApplication.CreateBuilder(args);
var username = builder.AddParameter("username");
var password = builder.AddParameter("password", secret: true);
var keycloak = builder.AddKeycloak("keycloak", 8080, username, password);
var apiService = builder.AddProject<Projects.Keycloak_ApiService>("apiservice")
.WithReference(keycloak)
.WaitFor(keycloak);
builder.AddProject<Projects.Keycloak_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(keycloak)
.WithReference(apiService)
.WaitFor(apiService);
// After adding all resources, run the app...
username
パラメーターと password
パラメーターは、通常、環境変数またはシークレットとして提供されます。 パラメーターは、コンテナー内の KEYCLOAK_ADMIN
および KEYCLOAK_ADMIN_PASSWORD
環境変数を設定するために使用されます。 パラメーターの指定の詳細については、「外部パラメーターの
領域インポートでKeycloakリソースを追加する
領域を Keycloakにインポートするには、WithRealmImport メソッドを呼び出します。
var builder = DistributedApplication.CreateBuilder(args);
var keycloak = builder.AddKeycloak("keycloak", 8080)
.WithDataVolume()
.WithRealmImport("./Realms");
var apiService = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReference(keycloak)
.WaitFor(keycloak);
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(keycloak)
.WithReference(apiService)
.WaitFor(apiService);
builder.Build().Run();
領域インポート ファイルは、Keycloak コンテナー内の /opt/keycloak/data/import
にマウントされます。 領域インポート・ファイルは、領域構成を表す JSON・ファイルです。 領域のインポートの詳細については、「Keycloak ドキュメント: 領域のインポート」を参照してください。
たとえば、次の JSON ファイルを /Realms フォルダー内のアプリ ホスト プロジェクトに追加して、ソース領域構成ファイルとして機能することができます。
領域 JSON 例を切り替えます。
{
"id": "86683c73-be28-4380-a014-6316c0404192",
"realm": "WeatherShop",
"notBefore": 0,
"defaultSignatureAlgorithm": "RS256",
"revokeRefreshToken": false,
"refreshTokenMaxReuse": 0,
"accessTokenLifespan": 300,
"accessTokenLifespanForImplicitFlow": 900,
"ssoSessionIdleTimeout": 1800,
"ssoSessionMaxLifespan": 36000,
"ssoSessionIdleTimeoutRememberMe": 0,
"ssoSessionMaxLifespanRememberMe": 0,
"offlineSessionIdleTimeout": 2592000,
"offlineSessionMaxLifespanEnabled": false,
"offlineSessionMaxLifespan": 5184000,
"clientSessionIdleTimeout": 0,
"clientSessionMaxLifespan": 0,
"clientOfflineSessionIdleTimeout": 0,
"clientOfflineSessionMaxLifespan": 0,
"accessCodeLifespan": 60,
"accessCodeLifespanUserAction": 300,
"accessCodeLifespanLogin": 1800,
"actionTokenGeneratedByAdminLifespan": 43200,
"actionTokenGeneratedByUserLifespan": 300,
"oauth2DeviceCodeLifespan": 600,
"oauth2DevicePollingInterval": 5,
"enabled": true,
"sslRequired": "external",
"registrationAllowed": true,
"registrationEmailAsUsername": false,
"rememberMe": false,
"verifyEmail": false,
"loginWithEmailAllowed": true,
"duplicateEmailsAllowed": false,
"resetPasswordAllowed": false,
"editUsernameAllowed": false,
"bruteForceProtected": false,
"permanentLockout": false,
"maxTemporaryLockouts": 0,
"maxFailureWaitSeconds": 900,
"minimumQuickLoginWaitSeconds": 60,
"waitIncrementSeconds": 60,
"quickLoginCheckMilliSeconds": 1000,
"maxDeltaTimeSeconds": 43200,
"failureFactor": 30,
"roles": {
"realm": [
{
"id": "79e15e0c-7084-4595-9066-c852bc5a6aca",
"name": "uma_authorization",
"description": "${role_uma_authorization}",
"composite": false,
"clientRole": false,
"containerId": "86683c73-be28-4380-a014-6316c0404192",
"attributes": {}
},
{
"id": "f2bd959d-ed9d-4409-af6d-206a4a52cc23",
"name": "default-roles-weathershop",
"description": "${role_default-roles}",
"composite": true,
"composites": {
"realm": [ "offline_access", "uma_authorization" ],
"client": {
"account": [ "view-profile", "manage-account" ]
}
},
"clientRole": false,
"containerId": "86683c73-be28-4380-a014-6316c0404192",
"attributes": {}
},
{
"id": "5e1d3cf6-c7ac-478d-a70c-4299abf58490",
"name": "offline_access",
"description": "${role_offline-access}",
"composite": false,
"clientRole": false,
"containerId": "86683c73-be28-4380-a014-6316c0404192",
"attributes": {}
}
],
"client": {
"realm-management": [
{
"id": "fe6e42fe-8629-40da-9afe-1179fc964988",
"name": "manage-users",
"description": "${role_manage-users}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "f82abb6c-239c-4533-afbd-a7aa03937204",
"name": "view-users",
"description": "${role_view-users}",
"composite": true,
"composites": {
"client": {
"realm-management": [ "query-groups", "query-users" ]
}
},
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "1eb57351-1302-45e5-924a-9b0dc337a2bb",
"name": "view-events",
"description": "${role_view-events}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "df3a077e-9bd4-4924-8281-cab7c7fd73e3",
"name": "manage-authorization",
"description": "${role_manage-authorization}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "d9fcb43a-3bad-492c-9af9-f199a6382064",
"name": "query-groups",
"description": "${role_query-groups}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "1dbdaf2b-a29c-4c54-86b7-d7c338e7672f",
"name": "realm-admin",
"description": "${role_realm-admin}",
"composite": true,
"composites": {
"client": {
"realm-management": [ "view-users", "manage-users", "view-events", "query-groups", "manage-authorization", "query-users", "manage-realm", "view-identity-providers", "create-client", "view-authorization", "query-clients", "view-clients", "query-realms", "impersonation", "view-realm", "manage-events", "manage-identity-providers", "manage-clients" ]
}
},
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "4c1ff7e3-cc1d-4b1d-a88f-fb71416c742a",
"name": "query-users",
"description": "${role_query-users}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "284b35f8-5bc2-4482-8769-81d3594df5a3",
"name": "manage-realm",
"description": "${role_manage-realm}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "7e872c38-8a22-469f-92ca-ec67e95d3c33",
"name": "view-identity-providers",
"description": "${role_view-identity-providers}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "9f4c2563-7575-461e-b2c8-b2b87f314cb9",
"name": "create-client",
"description": "${role_create-client}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "8f92f45c-bfa0-4a66-9812-334fe223c8be",
"name": "query-clients",
"description": "${role_query-clients}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "2a0143cf-ad90-4f68-bcb2-a50aa358b070",
"name": "view-authorization",
"description": "${role_view-authorization}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "95cc13bf-1342-445a-99fd-141522a7e777",
"name": "view-clients",
"description": "${role_view-clients}",
"composite": true,
"composites": {
"client": {
"realm-management": [ "query-clients" ]
}
},
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "109f4b83-ba7d-4036-91e7-7e169cd4c30c",
"name": "query-realms",
"description": "${role_query-realms}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "17bcb2b7-3a35-4089-85ea-1d034303b5d6",
"name": "impersonation",
"description": "${role_impersonation}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "21c51846-5f22-4318-82b7-9e64e2d256f4",
"name": "view-realm",
"description": "${role_view-realm}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "a0599e32-b53b-43bf-a7f6-ac0507ed277d",
"name": "manage-events",
"description": "${role_manage-events}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "e732e665-efb7-4df0-8843-b22bf2fe4717",
"name": "manage-identity-providers",
"description": "${role_manage-identity-providers}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
},
{
"id": "6d1b10f2-4c51-4279-8418-d4b82c17f203",
"name": "manage-clients",
"description": "${role_manage-clients}",
"composite": false,
"clientRole": true,
"containerId": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"attributes": {}
}
],
"WeatherWeb": [],
"security-admin-console": [],
"admin-cli": [],
"account-console": [],
"broker": [
{
"id": "7184260f-55c4-454a-bf67-dade5b74df7e",
"name": "read-token",
"description": "${role_read-token}",
"composite": false,
"clientRole": true,
"containerId": "db2ab30c-b83b-499e-9545-decdc906a372",
"attributes": {}
}
],
"Postman": [],
"weather.api": [],
"account": [
{
"id": "b4a01a53-3ed0-4e96-8fd1-efb0c143a45d",
"name": "view-groups",
"description": "${role_view-groups}",
"composite": false,
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
},
{
"id": "e9af1e5f-c0a5-4515-a77a-38fec79135d0",
"name": "delete-account",
"description": "${role_delete-account}",
"composite": false,
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
},
{
"id": "526cc4f7-6cf8-4f2b-8241-de0e60d2fd47",
"name": "manage-consent",
"description": "${role_manage-consent}",
"composite": true,
"composites": {
"client": {
"account": [ "view-consent" ]
}
},
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
},
{
"id": "cf93d42f-ffd9-4b3f-bf8d-55aa934f2fe3",
"name": "view-applications",
"description": "${role_view-applications}",
"composite": false,
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
},
{
"id": "f3b44155-fe06-4fea-8b8f-6954f54d48bb",
"name": "view-profile",
"description": "${role_view-profile}",
"composite": false,
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
},
{
"id": "65a74b6a-a00f-46b6-8ead-6c051e78c37e",
"name": "manage-account",
"description": "${role_manage-account}",
"composite": true,
"composites": {
"client": {
"account": [ "manage-account-links" ]
}
},
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
},
{
"id": "c914cc47-8a49-4f30-9851-6f639c4e7adf",
"name": "manage-account-links",
"description": "${role_manage-account-links}",
"composite": false,
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
},
{
"id": "261d0db4-28c7-4900-a156-01ab4e2483e5",
"name": "view-consent",
"description": "${role_view-consent}",
"composite": false,
"clientRole": true,
"containerId": "65816a45-48d3-4856-b052-c65cb03881d3",
"attributes": {}
}
]
}
},
"groups": [],
"defaultRole": {
"id": "f2bd959d-ed9d-4409-af6d-206a4a52cc23",
"name": "default-roles-weathershop",
"description": "${role_default-roles}",
"composite": true,
"clientRole": false,
"containerId": "86683c73-be28-4380-a014-6316c0404192"
},
"requiredCredentials": [ "password" ],
"otpPolicyType": "totp",
"otpPolicyAlgorithm": "HmacSHA1",
"otpPolicyInitialCounter": 0,
"otpPolicyDigits": 6,
"otpPolicyLookAheadWindow": 1,
"otpPolicyPeriod": 30,
"otpPolicyCodeReusable": false,
"otpSupportedApplications": [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ],
"localizationTexts": {},
"webAuthnPolicyRpEntityName": "keycloak",
"webAuthnPolicySignatureAlgorithms": [ "ES256" ],
"webAuthnPolicyRpId": "",
"webAuthnPolicyAttestationConveyancePreference": "not specified",
"webAuthnPolicyAuthenticatorAttachment": "not specified",
"webAuthnPolicyRequireResidentKey": "not specified",
"webAuthnPolicyUserVerificationRequirement": "not specified",
"webAuthnPolicyCreateTimeout": 0,
"webAuthnPolicyAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyAcceptableAaguids": [],
"webAuthnPolicyExtraOrigins": [],
"webAuthnPolicyPasswordlessRpEntityName": "keycloak",
"webAuthnPolicyPasswordlessSignatureAlgorithms": [ "ES256" ],
"webAuthnPolicyPasswordlessRpId": "",
"webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
"webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
"webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
"webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
"webAuthnPolicyPasswordlessCreateTimeout": 0,
"webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
"webAuthnPolicyPasswordlessAcceptableAaguids": [],
"webAuthnPolicyPasswordlessExtraOrigins": [],
"scopeMappings": [
{
"clientScope": "offline_access",
"roles": [ "offline_access" ]
}
],
"clientScopeMappings": {
"account": [
{
"client": "account-console",
"roles": [ "manage-account", "view-groups" ]
}
]
},
"clients": [
{
"id": "bd03dd61-71bf-4f50-acfa-bfc2444ee1d2",
"clientId": "Postman",
"name": "",
"description": "",
"rootUrl": "",
"adminUrl": "",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [ "https://oauth.pstmn.io/v1/callback" ],
"webOrigins": [ "https://oauth.pstmn.io" ],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": true,
"protocol": "openid-connect",
"attributes": {
"oidc.ciba.grant.enabled": "false",
"client.secret.creation.time": "1718111570",
"backchannel.logout.session.required": "true",
"post.logout.redirect.uris": "+",
"oauth2.device.authorization.grant.enabled": "false",
"display.on.consent.screen": "false",
"backchannel.logout.revoke.offline.tokens": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "weather:all", "microprofile-jwt" ]
},
{
"id": "016c17d1-8e0f-4a67-9116-86b4691ba99c",
"clientId": "WeatherWeb",
"name": "",
"description": "",
"rootUrl": "",
"adminUrl": "",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [ "https://localhost:7085/signin-oidc" ],
"webOrigins": [ "https://localhost:7085" ],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": true,
"protocol": "openid-connect",
"attributes": {
"oidc.ciba.grant.enabled": "false",
"post.logout.redirect.uris": "https://localhost:7085/signout-callback-oidc",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.session.required": "true",
"backchannel.logout.revoke.offline.tokens": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "weather:all", "microprofile-jwt" ]
},
{
"id": "65816a45-48d3-4856-b052-c65cb03881d3",
"clientId": "account",
"name": "${client_account}",
"rootUrl": "${authBaseUrl}",
"baseUrl": "/realms/WeatherShop/account/",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [ "/realms/WeatherShop/account/*" ],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"post.logout.redirect.uris": "+"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"nodeReRegistrationTimeout": 0,
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ]
},
{
"id": "437fda77-3ba1-4d7b-b192-808e4e62833b",
"clientId": "account-console",
"name": "${client_account-console}",
"rootUrl": "${authBaseUrl}",
"baseUrl": "/realms/WeatherShop/account/",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [ "/realms/WeatherShop/account/*" ],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"post.logout.redirect.uris": "+",
"pkce.code.challenge.method": "S256"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"nodeReRegistrationTimeout": 0,
"protocolMappers": [
{
"id": "e4606d8a-a581-402c-9290-4e3b988f2090",
"name": "audience resolve",
"protocol": "openid-connect",
"protocolMapper": "oidc-audience-resolve-mapper",
"consentRequired": false,
"config": {}
}
],
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ]
},
{
"id": "f13fd042-6931-4032-a0ba-f63b364f8d56",
"clientId": "admin-cli",
"name": "${client_admin-cli}",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": false,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"post.logout.redirect.uris": "+"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"nodeReRegistrationTimeout": 0,
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ]
},
{
"id": "db2ab30c-b83b-499e-9545-decdc906a372",
"clientId": "broker",
"name": "${client_broker}",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": true,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"post.logout.redirect.uris": "+"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"nodeReRegistrationTimeout": 0,
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ]
},
{
"id": "0aa2db92-8cc4-490f-a084-55f5b889613a",
"clientId": "realm-management",
"name": "${client_realm-management}",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": true,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"post.logout.redirect.uris": "+"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"nodeReRegistrationTimeout": 0,
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ]
},
{
"id": "e0cc9cef-924e-4799-a921-4811f3bb5d65",
"clientId": "security-admin-console",
"name": "${client_security-admin-console}",
"rootUrl": "${authAdminUrl}",
"baseUrl": "/admin/WeatherShop/console/",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [ "/admin/WeatherShop/console/*" ],
"webOrigins": [ "+" ],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"post.logout.redirect.uris": "+",
"pkce.code.challenge.method": "S256"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": false,
"nodeReRegistrationTimeout": 0,
"protocolMappers": [
{
"id": "254ac20c-6701-4095-82c6-6abd6669b9de",
"name": "locale",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "locale",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "locale",
"jsonType.label": "String"
}
}
],
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ]
},
{
"id": "4b5953fd-b218-41be-b061-58f37c1c7d26",
"clientId": "weather.api",
"name": "",
"description": "",
"rootUrl": "",
"adminUrl": "",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"secret": "**********",
"redirectUris": [ "/*" ],
"webOrigins": [ "/*" ],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": true,
"protocol": "openid-connect",
"attributes": {
"oidc.ciba.grant.enabled": "false",
"client.secret.creation.time": "1718111354",
"backchannel.logout.session.required": "true",
"post.logout.redirect.uris": "+",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [ "web-origins", "acr", "profile", "roles", "email" ],
"optionalClientScopes": [ "address", "phone", "offline_access", "microprofile-jwt" ]
}
],
"clientScopes": [
{
"id": "2a6322a2-2f6a-469f-b3c7-d0922db4ad46",
"name": "phone",
"description": "OpenID Connect built-in scope: phone",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"consent.screen.text": "${phoneScopeConsentText}"
},
"protocolMappers": [
{
"id": "ab515c55-d65b-42d3-9d3c-18921a8df065",
"name": "phone number",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "phoneNumber",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "phone_number",
"jsonType.label": "String"
}
},
{
"id": "bfaa5db4-137c-4824-bfae-ed77762872c2",
"name": "phone number verified",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "phoneNumberVerified",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "phone_number_verified",
"jsonType.label": "boolean"
}
}
]
},
{
"id": "52fc55cb-995e-4aa2-95ae-3b3d6601dc41",
"name": "weather:all",
"description": "",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"gui.order": "",
"consent.screen.text": ""
},
"protocolMappers": [
{
"id": "06d03e02-1e56-4bde-911d-bcf28aeba90f",
"name": "weather api audience",
"protocol": "openid-connect",
"protocolMapper": "oidc-audience-mapper",
"consentRequired": false,
"config": {
"included.client.audience": "weather.api",
"introspection.token.claim": "true",
"userinfo.token.claim": "false",
"id.token.claim": "false",
"lightweight.claim": "false",
"access.token.claim": "true"
}
}
]
},
{
"id": "292ded65-c85e-4c56-ad4d-8e886b9bb261",
"name": "email",
"description": "OpenID Connect built-in scope: email",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"consent.screen.text": "${emailScopeConsentText}"
},
"protocolMappers": [
{
"id": "42743882-7e0a-455e-b6a3-794ec8bf0f22",
"name": "email verified",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-property-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "emailVerified",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "email_verified",
"jsonType.label": "boolean"
}
},
{
"id": "b6dd2af9-e583-4d01-95fa-3f0db3ab0129",
"name": "email",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "email",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "email",
"jsonType.label": "String"
}
}
]
},
{
"id": "09a76939-4997-49f5-b88e-dfe54a2819f5",
"name": "offline_access",
"description": "OpenID Connect built-in scope: offline_access",
"protocol": "openid-connect",
"attributes": {
"consent.screen.text": "${offlineAccessScopeConsentText}",
"display.on.consent.screen": "true"
}
},
{
"id": "95ff8627-716e-49f0-b960-52185409d628",
"name": "profile",
"description": "OpenID Connect built-in scope: profile",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"consent.screen.text": "${profileScopeConsentText}"
},
"protocolMappers": [
{
"id": "b1ae43d1-9d52-40cd-9c6a-a8557ea63f9a",
"name": "picture",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "picture",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "picture",
"jsonType.label": "String"
}
},
{
"id": "b9e09b82-3e67-4175-b34a-419b24a13a7f",
"name": "zoneinfo",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "zoneinfo",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "zoneinfo",
"jsonType.label": "String"
}
},
{
"id": "06e88533-d2cc-4ae3-a25a-a17e93f69dee",
"name": "nickname",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "nickname",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "nickname",
"jsonType.label": "String"
}
},
{
"id": "b697c055-2fb9-4985-8919-33d9f524eaa9",
"name": "full name",
"protocol": "openid-connect",
"protocolMapper": "oidc-full-name-mapper",
"consentRequired": false,
"config": {
"id.token.claim": "true",
"introspection.token.claim": "true",
"access.token.claim": "true",
"userinfo.token.claim": "true"
}
},
{
"id": "70663048-2110-4271-a8f4-105e77fe2905",
"name": "profile",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "profile",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "profile",
"jsonType.label": "String"
}
},
{
"id": "85c992ed-4971-41f1-a4b8-c6263b29dff8",
"name": "website",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "website",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "website",
"jsonType.label": "String"
}
},
{
"id": "49e1d494-a72e-49de-a5de-8c2ad752205c",
"name": "birthdate",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "birthdate",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "birthdate",
"jsonType.label": "String"
}
},
{
"id": "a746724f-7622-4ad4-91ef-811da6c735ad",
"name": "updated at",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "updatedAt",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "updated_at",
"jsonType.label": "long"
}
},
{
"id": "d647d13f-9f96-49f3-b32a-62ad63c37d0e",
"name": "gender",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "gender",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "gender",
"jsonType.label": "String"
}
},
{
"id": "86204f6f-16ce-4c9f-9fca-f66b3f292554",
"name": "given name",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "firstName",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "given_name",
"jsonType.label": "String"
}
},
{
"id": "f4005bd9-18d2-4456-9e7c-98c5a637f063",
"name": "locale",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "locale",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "locale",
"jsonType.label": "String"
}
},
{
"id": "04b20a5a-1588-476c-a465-26a691320510",
"name": "family name",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "lastName",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "family_name",
"jsonType.label": "String"
}
},
{
"id": "f812580a-7863-44c3-bcf0-c3f441f0194e",
"name": "middle name",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "middleName",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "middle_name",
"jsonType.label": "String"
}
},
{
"id": "c2ae83c9-62c2-4a65-adef-c1d6fd126ec4",
"name": "username",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "username",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "preferred_username",
"jsonType.label": "String"
}
}
]
},
{
"id": "3ab2520f-feb4-43fd-9256-fa9f3e521aa7",
"name": "address",
"description": "OpenID Connect built-in scope: address",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "true",
"consent.screen.text": "${addressScopeConsentText}"
},
"protocolMappers": [
{
"id": "b083371e-07ae-4b01-9e8c-6a54b396359f",
"name": "address",
"protocol": "openid-connect",
"protocolMapper": "oidc-address-mapper",
"consentRequired": false,
"config": {
"user.attribute.formatted": "formatted",
"user.attribute.country": "country",
"introspection.token.claim": "true",
"user.attribute.postal_code": "postal_code",
"userinfo.token.claim": "true",
"user.attribute.street": "street",
"id.token.claim": "true",
"user.attribute.region": "region",
"access.token.claim": "true",
"user.attribute.locality": "locality"
}
}
]
},
{
"id": "fda66a99-e8b6-49e6-9186-0a7026ec0275",
"name": "web-origins",
"description": "OpenID Connect scope for add allowed web origins to the access token",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "false",
"display.on.consent.screen": "false",
"consent.screen.text": ""
},
"protocolMappers": [
{
"id": "4b12d4de-8c05-4251-9c8f-f801cfa3bf2a",
"name": "allowed web origins",
"protocol": "openid-connect",
"protocolMapper": "oidc-allowed-origins-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"access.token.claim": "true"
}
}
]
},
{
"id": "581928cd-35d7-4c79-a9d1-4e1c9c8ade7e",
"name": "acr",
"description": "OpenID Connect scope for add acr (authentication context class reference) to the token",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "false",
"display.on.consent.screen": "false"
},
"protocolMappers": [
{
"id": "d664d3db-be9f-4fee-a72a-be6a295c47f5",
"name": "acr loa level",
"protocol": "openid-connect",
"protocolMapper": "oidc-acr-mapper",
"consentRequired": false,
"config": {
"id.token.claim": "true",
"introspection.token.claim": "true",
"access.token.claim": "true",
"userinfo.token.claim": "true"
}
}
]
},
{
"id": "9ac2f136-a665-4550-ac77-cc61a1cd1e95",
"name": "role_list",
"description": "SAML role list",
"protocol": "saml",
"attributes": {
"consent.screen.text": "${samlRoleListScopeConsentText}",
"display.on.consent.screen": "true"
},
"protocolMappers": [
{
"id": "040520c7-9dfb-4f9d-a93e-17e3267b1517",
"name": "role list",
"protocol": "saml",
"protocolMapper": "saml-role-list-mapper",
"consentRequired": false,
"config": {
"single": "false",
"attribute.nameformat": "Basic",
"attribute.name": "Role"
}
}
]
},
{
"id": "f0ff8363-c507-4113-adc0-47f6b346de26",
"name": "roles",
"description": "OpenID Connect scope for add user roles to the access token",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "false",
"display.on.consent.screen": "true",
"consent.screen.text": "${rolesScopeConsentText}"
},
"protocolMappers": [
{
"id": "13aa2234-81bf-4018-a67c-d657045eac1f",
"name": "client roles",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-client-role-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"multivalued": "true",
"user.attribute": "foo",
"access.token.claim": "true",
"claim.name": "resource_access.${client_id}.roles",
"jsonType.label": "String"
}
},
{
"id": "d0b63e0d-5543-41dc-baf6-1c6987d6a18d",
"name": "audience resolve",
"protocol": "openid-connect",
"protocolMapper": "oidc-audience-resolve-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"access.token.claim": "true"
}
},
{
"id": "38881c98-4009-412b-b924-d36f55273f3e",
"name": "realm roles",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-realm-role-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"multivalued": "true",
"user.attribute": "foo",
"access.token.claim": "true",
"claim.name": "realm_access.roles",
"jsonType.label": "String"
}
}
]
},
{
"id": "b8a70a2a-a24d-4862-ad4b-dd737b60f7ce",
"name": "microprofile-jwt",
"description": "Microprofile - JWT built-in scope",
"protocol": "openid-connect",
"attributes": {
"include.in.token.scope": "true",
"display.on.consent.screen": "false"
},
"protocolMappers": [
{
"id": "4eb888ff-b503-4506-b35c-ea0ac0ff3cd3",
"name": "groups",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-realm-role-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"multivalued": "true",
"userinfo.token.claim": "true",
"user.attribute": "foo",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "groups",
"jsonType.label": "String"
}
},
{
"id": "d39896cb-3f45-4a62-a254-f7d0eb10e60a",
"name": "upn",
"protocol": "openid-connect",
"protocolMapper": "oidc-usermodel-attribute-mapper",
"consentRequired": false,
"config": {
"introspection.token.claim": "true",
"userinfo.token.claim": "true",
"user.attribute": "username",
"id.token.claim": "true",
"access.token.claim": "true",
"claim.name": "upn",
"jsonType.label": "String"
}
}
]
}
],
"defaultDefaultClientScopes": [ "role_list", "profile", "email", "roles", "web-origins", "acr" ],
"defaultOptionalClientScopes": [ "offline_access", "address", "phone", "microprofile-jwt", "weather:all" ],
"browserSecurityHeaders": {
"contentSecurityPolicyReportOnly": "",
"xContentTypeOptions": "nosniff",
"referrerPolicy": "no-referrer",
"xRobotsTag": "none",
"xFrameOptions": "SAMEORIGIN",
"contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
"xXSSProtection": "1; mode=block",
"strictTransportSecurity": "max-age=31536000; includeSubDomains"
},
"smtpServer": {},
"eventsEnabled": false,
"eventsListeners": [ "jboss-logging" ],
"enabledEventTypes": [],
"adminEventsEnabled": false,
"adminEventsDetailsEnabled": false,
"identityProviders": [],
"identityProviderMappers": [],
"components": {
"org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [
{
"id": "887848c6-60f6-47ac-ae7f-62f8a5608a4b",
"name": "Trusted Hosts",
"providerId": "trusted-hosts",
"subType": "anonymous",
"subComponents": {},
"config": {
"host-sending-registration-request-must-match": [ "true" ],
"client-uris-must-match": [ "true" ]
}
},
{
"id": "4333143f-bf59-419a-99e2-2cce8a5d414a",
"name": "Consent Required",
"providerId": "consent-required",
"subType": "anonymous",
"subComponents": {},
"config": {}
},
{
"id": "1ac2db3a-57a1-4567-bc2b-80a2b0c96b71",
"name": "Max Clients Limit",
"providerId": "max-clients",
"subType": "anonymous",
"subComponents": {},
"config": {
"max-clients": [ "200" ]
}
},
{
"id": "adb4b546-6386-46e0-8ce9-80bacbba2afe",
"name": "Allowed Protocol Mapper Types",
"providerId": "allowed-protocol-mappers",
"subType": "authenticated",
"subComponents": {},
"config": {
"allowed-protocol-mapper-types": [ "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "saml-role-list-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper" ]
}
},
{
"id": "241c5dea-68b9-4684-a816-80b08ef86bff",
"name": "Full Scope Disabled",
"providerId": "scope",
"subType": "anonymous",
"subComponents": {},
"config": {}
},
{
"id": "6b0e159c-33dc-492b-9d88-421973015466",
"name": "Allowed Protocol Mapper Types",
"providerId": "allowed-protocol-mappers",
"subType": "anonymous",
"subComponents": {},
"config": {
"allowed-protocol-mapper-types": [ "saml-user-property-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-full-name-mapper" ]
}
},
{
"id": "730409bc-ce7e-4b64-a870-946aeba9f65b",
"name": "Allowed Client Scopes",
"providerId": "allowed-client-templates",
"subType": "anonymous",
"subComponents": {},
"config": {
"allow-default-scopes": [ "true" ]
}
},
{
"id": "0b4b8c74-20b6-4902-b971-9b97001da41e",
"name": "Allowed Client Scopes",
"providerId": "allowed-client-templates",
"subType": "authenticated",
"subComponents": {},
"config": {
"allow-default-scopes": [ "true" ]
}
}
],
"org.keycloak.keys.KeyProvider": [
{
"id": "c08db9a9-0d9d-4b56-96d5-7f2b1d4528df",
"name": "rsa-generated",
"providerId": "rsa-generated",
"subComponents": {},
"config": {
"privateKey": [ "MIIEowIBAAKCAQEAyJtAKWr1DdQmh9Nxp2LUGOrc5OA+rdXkV6+kOT21wVsIP/1bg6HekqfMySZhIxlALfegc90j0mrqkolb5s7axotTwwABwIvgxW5hHIQ4huntiZUYPUuf4m51dwyLs/GM1gSbzs9ciBKC5i4S21CQzuGp0QHpyOOn1kQZd0vYSGjpG3ewMYphJEfd60TQP74RcqASNoOaS3lU7+5SCQuiff1fSZYqYvIFmK3rcNrauTSryx6rh935ODSdYzQN0XA6g1WJK2hbBlBJJzeAj/CXXcBaw7aB1AoC7kjJ7XaYmHdC+7zIYhvNKcGtFhrMjoOVnJM9PiRMrk7ous7XAmKc6QIDAQABAoIBAC4qjm5Js1oqnfBpwJDrPVD7sfjJQ5t5azqjzQkwUrUMGF6zlZ06QhDhpY8QMlAjxkGd6JLpjE4nNVMiYeBA8Be7pjvs8zpG5qRBBf/MTP79dGFSitjGX+X6EjXi0P7JIuZ4+otybMLS8cV7ynKm/KBjzhMv28fT3oMAupSaA40MESKVD8BDR0bNQ6H3h1xrq2+81xViFsle9qcrZjJzCz/rttNi3DUct5IeJwc9Wai937L6H/BU5eBd9vQHM5raLL0iDSF5CQF2tE/j3hq8kdpRm9XRUm/0WaXOz8Il96GfSEUXLVvKnLdHu7qYbqKKBYI7B3xz8VYiHgDvBMqiBzUCgYEA9Sd/EijWpXAAaFOJk75BOu0sSjZHjoGbaLE1XWsQyM1fkFT9kxQ+8/kDiHSJal+utoEIrMWK/KdrrIjT0TXbWKCarV+ebgCt9dkTd6Or2SUku5k0TMSMoVEI2KxI6ZHvCz2Vxe8Ahbao28u8xOGRQYSs5ynvH0oBTex+RP3sv6UCgYEA0Xs55XdSn1PGazAuZYk9ZKJhCovdalYdjnJYxuSPfBgHV4CIHdhHvd/hohumMakQsnRDmJzbk/uFlqJecZtcQ/DukGylC/6dvfp6prUrVhghK+7+Bnry7zfQ9rMWslrlhf9ZTrQ8F9pssCtgAfs+Pfj0zF5DxQqFqF3wz12sJPUCgYATR5HkubV3uUEu8zLknZe/rJtJEs+501OHfjg2Ko9dW1linmx6vqLcyP6QIqoT5YZ179vgyoBNslTzcqdF0rh3VdoUPGrXN9J2fSXcyNBg+VzULA5C40oz/Y12jMYHKGTmO2el80/VNDI/Ztxnl123C1oVq+SUT1ue5zRe9KFDyQKBgBihnqsmnqZxWVFdNvdlbbyZg0OUMpLAUXVgaKPqWBzFToexa0/nEHh5DLTc/2uzb20sUo5tUzxRROHzcZt2IyEyATsmKzn/1Fh0TVuwzcmvyKa70U69wjbynzWC1VZfbcGVxtCETNSZMFJ+pylUe3sZ/N7S7rEKjbDAawJXB1jJAoGBAOZF4M9C1GLCZqt4RrF1MBI0Q+7Im45Hvr0FSck0y9xLpl9yolQREWoiCo5+WM54YMeSWu0rzBsLAjCoFpIX2cWcICsdPAnyyjIMPmuGt/uUaIWmq/ZRAsqkOW0sqxUMggjytNCtvdCyfQOcKsEHpBKrA6z+8l/3Z1RQFwan+VPs" ],
"certificate": [ "MIICpTCCAY0CBgGQcJfMUjANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtXZWF0aGVyU2hvcDAeFw0yNDA3MDEyMzE2NTRaFw0zNDA3MDEyMzE4MzRaMBYxFDASBgNVBAMMC1dlYXRoZXJTaG9wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyJtAKWr1DdQmh9Nxp2LUGOrc5OA+rdXkV6+kOT21wVsIP/1bg6HekqfMySZhIxlALfegc90j0mrqkolb5s7axotTwwABwIvgxW5hHIQ4huntiZUYPUuf4m51dwyLs/GM1gSbzs9ciBKC5i4S21CQzuGp0QHpyOOn1kQZd0vYSGjpG3ewMYphJEfd60TQP74RcqASNoOaS3lU7+5SCQuiff1fSZYqYvIFmK3rcNrauTSryx6rh935ODSdYzQN0XA6g1WJK2hbBlBJJzeAj/CXXcBaw7aB1AoC7kjJ7XaYmHdC+7zIYhvNKcGtFhrMjoOVnJM9PiRMrk7ous7XAmKc6QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAeDhADaUkVzu1o8CvCfU9oa6hGsJa+2qFeUPQnG7HZAQ07MjQ/RZgMMOmdhspZIuaf+Yrx/My8VDphKzNtb2eNHgFVVQDy1F1jVy9z+t7xCwX3UfjtVNMp3tMmzWUEi0pckW0mq4Bz3w0+dKPw8z0K2c19dVN1NHDViqFghB+77tO8JguwTDE8fkmXjLixDCcenBCPXjxNWmhXgOMF1wKhlq1h0+SaKt/F2P/WzyoYu6tz8qVysQvv4knB/HEGjSji+DN+uJFE4RJG+B5X+vp5LHvlYKIROQ7/aSzvCjx7zrslmcTsSTL3F1k2Ox2Hz+rGIcA8sGqbj+W5+nKxRbad" ],
"priority": [ "100" ]
}
},
{
"id": "9adc7ed1-f51b-48d4-9d52-96b46abefa18",
"name": "aes-generated",
"providerId": "aes-generated",
"subComponents": {},
"config": {
"kid": [ "eb1853e7-ac8c-4e8f-8b4f-9ea28a71da76" ],
"secret": [ "Jges9iPdpfx0aivf3RUUpw" ],
"priority": [ "100" ]
}
},
{
"id": "f4b81876-91be-46f3-9050-c351cd1531af",
"name": "rsa-enc-generated",
"providerId": "rsa-enc-generated",
"subComponents": {},
"config": {
"privateKey": [ "MIIEowIBAAKCAQEAlP+NrT2KVZpdrbPoTsMO7MqeXYDeJNl7IXjY0hCb7p1iB6YLOr/lA5ryk/CIHI05HRt+AEYFac87mb51SEvAa9cHjQ00v7t6hoYV1esyRmB0Nnf8AAEq9GoZxX9nUsIMcExQ3gHkF56kidYtjQSgl5SlwgdvlsjRiDP9ZJlsWTBb+8v0OCCbQLZFl93IlTZ7QlaxXoB0dCuuLNyBpELFbc0+JeB+1P/Dw5azUKGdp3ng2K9IrtDBiMh+KicpLZeBpUlqdKqyI2WvwruL1SlqH/ymWCxseRH0Z9VZ30MfW8C5fHq3qnLQp0OWDa7Re/pRbCZPabivDkZCtuWUeAVbRwIDAQABAoIBAAoioBaKuyA7kefA9yp0Zk2BMuiVXYcQLCoIuGcBrjm7BvISP21NpFxsa9fYYsneaWYrepS2LqQV7q30oLG8RWiQhfj4TwBD1n/UGyQkDZVv9jfGTaQKcEuT9BDVK8gbXxE8f7u6UTOyHOsrYInZKLtm5yedrd+J5YboUnJHZXFjmCpuyap8zJQdczUpZeLkj4bRqEHYlM1a5vfMFpr2+k4/Nqo36CCaGzIcwtYxnC002rL7ra9MaR1fy5KHtcoYQeePuPvXu1UxBU01+W1QmIsw+KmXftdtWYAMcVFkHDs+22h3mCxRhQqcxmL1LUP9FfGzrWiX4eTduw4YOkzO7+ECgYEAx732U2G7Qdp1uXsVGE7ceFcrpl/LOTaL8eEtULBiFRdrn5LOTAptpoDPB8vYCwIQSNrBWXNqTiDubOBcL7sumBK2i4Omtzk/USuMcJmSiMcHaANa/ZNK9nqtwMACqXpIPEkpofzfgBSaRYY1KxaWLbepyLjqviADV98zOI4qY28CgYEAvvbNd+C0pi5u/EkUxhRdxwCxICfkDYjArcjPU3ZBjIyAzmJ08wU+3CDm2sgts1TX+D7MPsRLqsaM8vMB+BR1xo3FfP/nqNvjYkChACtHhvkWGVE/qf3/53NNa4lKeVz8h1iV18dvLICj+V+lvUyQPuER4cA8Kzs7dObl52V6OakCgYB5bSkvPW2aNhV1QbbsRRzQZ6XYicnAqUFgNRTYRbIKwmch5hxVq81G+G1jfu+CmamOsLX0DC7m+iwXsjk4pyFHP7ELlWgnYLz2OnQxC5tCXURKXifVmdJrjt7MG65Cm10IkS2nFVRFx8CVXWY7IIsBlfK4XHoQROPjaoP38K0iLwKBgQCho6RdkR04ANu+vllQJNMP7B0Be+KENjnpn60mF1X6kr9AcoRNZCZGC698hq5wOiOoo/ccNelafz+1MU58X00lqMD+QlojSySX+N6OlxOvQs2a1nQN/sqKbcWdfZNFURkLs0b6Y3xN7gFdxsEyj0kVgEszjBUh/rwgAoWdrP6dKQKBgD2b7GG1/TPTBfOvvE7q7xa5IlTMUbBU2yY8H6XvDgfG5KUXXFpqINTOE4OjuyVwJRwE2/GQGayfZvfa+LGkW8Hy6Iz/vaa1Brjodza/2PblM5v1t96xA0WQDime8okJN0q7ocbLfQnT0+3TVMbvCjeBtOqmMOJT3EijpAqVbR6N" ],
"certificate": [ "MIICpTCCAY0CBgGQcJfM/jANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtXZWF0aGVyU2hvcDAeFw0yNDA3MDEyMzE2NTVaFw0zNDA3MDEyMzE4MzVaMBYxFDASBgNVBAMMC1dlYXRoZXJTaG9wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlP+NrT2KVZpdrbPoTsMO7MqeXYDeJNl7IXjY0hCb7p1iB6YLOr/lA5ryk/CIHI05HRt+AEYFac87mb51SEvAa9cHjQ00v7t6hoYV1esyRmB0Nnf8AAEq9GoZxX9nUsIMcExQ3gHkF56kidYtjQSgl5SlwgdvlsjRiDP9ZJlsWTBb+8v0OCCbQLZFl93IlTZ7QlaxXoB0dCuuLNyBpELFbc0+JeB+1P/Dw5azUKGdp3ng2K9IrtDBiMh+KicpLZeBpUlqdKqyI2WvwruL1SlqH/ymWCxseRH0Z9VZ30MfW8C5fHq3qnLQp0OWDa7Re/pRbCZPabivDkZCtuWUeAVbRwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAUIS+ce3NPCSk7iiA4vzm1hGrEq7Q+1CwE9hq/p8oKowOEVvg68tE+yzNsYw6qM+KKdzQfmiVeT8skDhNwL+5+Oxsg9dw7KW1me+g/pjiFx1eXt/rHN5aVDz7/F3QAP0G/CUF6dVNh0ggoGhwAH74iH91apmJgDUEBVzwaYCrHDJ81nWZOGZm4MF6FFvc8Kwf/+KEefL7psH5I4BqS+gRaPFWjBnABS7WkJ879gv0Q3tHE4KXF1b3eudGFrW4rG048pqNJgxAXdoDqFR5qIi9pfuE+HCmuhPv2Xq+I7S4PpUYnUM7o0Ng+1hJsRLhiG0Kmcepy7thiJJI619miVXdF" ],
"priority": [ "100" ],
"algorithm": [ "RSA-OAEP" ]
}
},
{
"id": "c962c2d9-ac19-4a91-88b3-959c6fcfc4c4",
"name": "hmac-generated-hs512",
"providerId": "hmac-generated",
"subComponents": {},
"config": {
"kid": [ "f43f7c3d-e27c-4a86-bda1-e1f9fa0b2c0b" ],
"secret": [ "FAyCBV9_zIF2oQO0XqgwCJz09iJDMKPHORhWI1ZV4OA9cLFVJCA-z4tEXq2QNU48xDMwv_z_UYIEm73nnJEypuaVwacu6N7jexaKjhqROYidQyPzXAr7QwD6Du1LaLdCAHaBo7rRP3Pl5fDmcX6K3C1Qe1OK86fkZVuD_2TX6No" ],
"priority": [ "100" ],
"algorithm": [ "HS512" ]
}
}
]
},
"internationalizationEnabled": false,
"supportedLocales": [],
"authenticationFlows": [
{
"id": "57c6972a-8262-4fdd-9a3d-6454f7e4804d",
"alias": "Account verification options",
"description": "Method with which to verity the existing account",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "idp-email-verification",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "ALTERNATIVE",
"priority": 20,
"autheticatorFlow": true,
"flowAlias": "Verify Existing Account by Re-authentication",
"userSetupAllowed": false
}
]
},
{
"id": "12219f2a-a63e-4e35-87b0-0c1fc82e9e00",
"alias": "Browser - Conditional OTP",
"description": "Flow to determine if the OTP is required for the authentication",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "conditional-user-configured",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "auth-otp-form",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
},
{
"id": "16a216e0-2305-4a26-8b3c-a1ad95ee0551",
"alias": "Direct Grant - Conditional OTP",
"description": "Flow to determine if the OTP is required for the authentication",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "conditional-user-configured",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "direct-grant-validate-otp",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
},
{
"id": "973a2638-3205-40a5-9ae1-171e862f98c2",
"alias": "First broker login - Conditional OTP",
"description": "Flow to determine if the OTP is required for the authentication",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "conditional-user-configured",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "auth-otp-form",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
},
{
"id": "d024eba2-74d6-4cd2-a149-eda663682a7b",
"alias": "Handle Existing Account",
"description": "Handle what to do if there is existing account with same email/username like authenticated identity provider",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "idp-confirm-link",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": true,
"flowAlias": "Account verification options",
"userSetupAllowed": false
}
]
},
{
"id": "37b5496c-9e09-402f-b079-9c588322f91d",
"alias": "Reset - Conditional OTP",
"description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "conditional-user-configured",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "reset-otp",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
},
{
"id": "62d51e78-668a-4d31-9369-0611a7507ed5",
"alias": "User creation or linking",
"description": "Flow for the existing/non-existing user alternatives",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticatorConfig": "create unique user config",
"authenticator": "idp-create-user-if-unique",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "ALTERNATIVE",
"priority": 20,
"autheticatorFlow": true,
"flowAlias": "Handle Existing Account",
"userSetupAllowed": false
}
]
},
{
"id": "ab6b9698-fd26-40a7-8edf-fa456a395394",
"alias": "Verify Existing Account by Re-authentication",
"description": "Reauthentication of existing account",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "idp-username-password-form",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "CONDITIONAL",
"priority": 20,
"autheticatorFlow": true,
"flowAlias": "First broker login - Conditional OTP",
"userSetupAllowed": false
}
]
},
{
"id": "74b79e04-bf44-4d84-92e7-04b753801622",
"alias": "browser",
"description": "browser based authentication",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "auth-cookie",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "auth-spnego",
"authenticatorFlow": false,
"requirement": "DISABLED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "identity-provider-redirector",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 25,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "ALTERNATIVE",
"priority": 30,
"autheticatorFlow": true,
"flowAlias": "forms",
"userSetupAllowed": false
}
]
},
{
"id": "bb15232e-9f1c-4dfd-8d10-e1d35cd1bfde",
"alias": "clients",
"description": "Base authentication for clients",
"providerId": "client-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "client-secret",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "client-jwt",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "client-secret-jwt",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 30,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "client-x509",
"authenticatorFlow": false,
"requirement": "ALTERNATIVE",
"priority": 40,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
},
{
"id": "dd3fe894-1594-40fb-949d-9986f36bd725",
"alias": "direct grant",
"description": "OpenID Connect Resource Owner Grant",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "direct-grant-validate-username",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "direct-grant-validate-password",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "CONDITIONAL",
"priority": 30,
"autheticatorFlow": true,
"flowAlias": "Direct Grant - Conditional OTP",
"userSetupAllowed": false
}
]
},
{
"id": "5c277901-3d67-470e-baf1-e47e9ab92dbd",
"alias": "docker auth",
"description": "Used by Docker clients to authenticate against the IDP",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "docker-http-basic-authenticator",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
},
{
"id": "e14e1d45-149f-4090-ad79-7c2d0c2f185c",
"alias": "first broker login",
"description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticatorConfig": "review profile config",
"authenticator": "idp-review-profile",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": true,
"flowAlias": "User creation or linking",
"userSetupAllowed": false
}
]
},
{
"id": "aa2e5d63-a8e9-43e4-8461-994827de67f5",
"alias": "forms",
"description": "Username, password, otp and other auth forms.",
"providerId": "basic-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "auth-username-password-form",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "CONDITIONAL",
"priority": 20,
"autheticatorFlow": true,
"flowAlias": "Browser - Conditional OTP",
"userSetupAllowed": false
}
]
},
{
"id": "d88b5042-8af8-4797-9c6a-ae44a9a0fff2",
"alias": "registration",
"description": "registration flow",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "registration-page-form",
"authenticatorFlow": true,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": true,
"flowAlias": "registration form",
"userSetupAllowed": false
}
]
},
{
"id": "2a9320cb-970e-4b4d-b585-60d2299a043f",
"alias": "registration form",
"description": "registration form",
"providerId": "form-flow",
"topLevel": false,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "registration-user-creation",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "registration-password-action",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 50,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "registration-recaptcha-action",
"authenticatorFlow": false,
"requirement": "DISABLED",
"priority": 60,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "registration-terms-and-conditions",
"authenticatorFlow": false,
"requirement": "DISABLED",
"priority": 70,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
},
{
"id": "528ba840-6b22-4c32-ba17-40c99783883e",
"alias": "reset credentials",
"description": "Reset credentials for a user if they forgot their password or something",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "reset-credentials-choose-user",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "reset-credential-email",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 20,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticator": "reset-password",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 30,
"autheticatorFlow": false,
"userSetupAllowed": false
},
{
"authenticatorFlow": true,
"requirement": "CONDITIONAL",
"priority": 40,
"autheticatorFlow": true,
"flowAlias": "Reset - Conditional OTP",
"userSetupAllowed": false
}
]
},
{
"id": "bf172b2d-052a-4ce4-9084-c59e9b82bc10",
"alias": "saml ecp",
"description": "SAML ECP Profile Authentication Flow",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": true,
"authenticationExecutions": [
{
"authenticator": "http-basic-authenticator",
"authenticatorFlow": false,
"requirement": "REQUIRED",
"priority": 10,
"autheticatorFlow": false,
"userSetupAllowed": false
}
]
}
],
"authenticatorConfig": [
{
"id": "796c70f7-6391-45ed-aafa-4ed82c84d14e",
"alias": "create unique user config",
"config": {
"require.password.update.after.registration": "false"
}
},
{
"id": "e007b422-2050-43af-b132-10ea16d92f5c",
"alias": "review profile config",
"config": {
"update.profile.on.first.login": "missing"
}
}
],
"requiredActions": [
{
"alias": "CONFIGURE_TOTP",
"name": "Configure OTP",
"providerId": "CONFIGURE_TOTP",
"enabled": true,
"defaultAction": false,
"priority": 10,
"config": {}
},
{
"alias": "TERMS_AND_CONDITIONS",
"name": "Terms and Conditions",
"providerId": "TERMS_AND_CONDITIONS",
"enabled": false,
"defaultAction": false,
"priority": 20,
"config": {}
},
{
"alias": "UPDATE_PASSWORD",
"name": "Update Password",
"providerId": "UPDATE_PASSWORD",
"enabled": true,
"defaultAction": false,
"priority": 30,
"config": {}
},
{
"alias": "UPDATE_PROFILE",
"name": "Update Profile",
"providerId": "UPDATE_PROFILE",
"enabled": true,
"defaultAction": false,
"priority": 40,
"config": {}
},
{
"alias": "VERIFY_EMAIL",
"name": "Verify Email",
"providerId": "VERIFY_EMAIL",
"enabled": true,
"defaultAction": false,
"priority": 50,
"config": {}
},
{
"alias": "delete_account",
"name": "Delete Account",
"providerId": "delete_account",
"enabled": false,
"defaultAction": false,
"priority": 60,
"config": {}
},
{
"alias": "webauthn-register",
"name": "Webauthn Register",
"providerId": "webauthn-register",
"enabled": true,
"defaultAction": false,
"priority": 70,
"config": {}
},
{
"alias": "webauthn-register-passwordless",
"name": "Webauthn Register Passwordless",
"providerId": "webauthn-register-passwordless",
"enabled": true,
"defaultAction": false,
"priority": 80,
"config": {}
},
{
"alias": "VERIFY_PROFILE",
"name": "Verify Profile",
"providerId": "VERIFY_PROFILE",
"enabled": true,
"defaultAction": false,
"priority": 90,
"config": {}
},
{
"alias": "delete_credential",
"name": "Delete Credential",
"providerId": "delete_credential",
"enabled": true,
"defaultAction": false,
"priority": 100,
"config": {}
},
{
"alias": "update_user_locale",
"name": "Update User Locale",
"providerId": "update_user_locale",
"enabled": true,
"defaultAction": false,
"priority": 1000,
"config": {}
}
],
"browserFlow": "browser",
"registrationFlow": "registration",
"directGrantFlow": "direct grant",
"resetCredentialsFlow": "reset credentials",
"clientAuthenticationFlow": "clients",
"dockerAuthenticationFlow": "docker auth",
"firstBrokerLoginFlow": "first broker login",
"attributes": {
"cibaBackchannelTokenDeliveryMode": "poll",
"cibaExpiresIn": "120",
"cibaAuthRequestedUserHint": "login_hint",
"oauth2DeviceCodeLifespan": "600",
"clientOfflineSessionMaxLifespan": "0",
"oauth2DevicePollingInterval": "5",
"clientSessionIdleTimeout": "0",
"parRequestUriLifespan": "60",
"clientSessionMaxLifespan": "0",
"clientOfflineSessionIdleTimeout": "0",
"cibaInterval": "5",
"realmReusableOtpCode": "false"
},
"keycloakVersion": "24.0.5",
"userManagedAccessAllowed": false,
"clientProfiles": {
"profiles": []
},
"clientPolicies": {
"policies": []
}
}
ホスティング統合の正常性チェック
Keycloak ホスティング統合は、現在、正常性チェックをサポートしていません。また、自動的に追加することもありません。
Client 統合
.NET Aspire Keycloak client 統合を開始するには、📦Aspireをインストールします。Keycloak.認証、clientを使用するプロジェクト、つまり、Keycloakclientを使用するアプリケーションのプロジェクト内の NuGet パッケージです。 Keycloak client 統合では、Keycloakに接続するために JwtBearer 認証ハンドラーと OpenId Connect 認証ハンドラーが DI コンテナーに登録されます。
dotnet add package Aspire.Keycloak.Authentication
JWT ベアラー認証を追加する
ASP.NET Core API プロジェクトの Program.cs ファイルで、AddKeycloakJwtBearer 拡張メソッドを呼び出し、接続名、領域、および必要な JWT ベアラー オプションを使用して JwtBearer 認証を追加します。
builder.Services.AddAuthentication()
.AddKeycloakJwtBearer(
serviceName: "keycloak",
realm: "api",
options =>
{
options.Audience = "store.api";
});
Action<JwtBearerOptions> configureOptions
デリゲートを使用して、他の多くのオプションを設定できます。
JWT ベアラー認証の例
JWT ベアラー認証をさらに例示するには、次の例を考えてみましょう。
var builder = WebApplication.CreateBuilder(args);
// Add service defaults & Aspire client integrations.
builder.AddServiceDefaults();
// Add services to the container.
builder.Services.AddProblemDetails();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddAuthentication()
.AddKeycloakJwtBearer(
serviceName: "keycloak",
realm: "WeatherShop",
configureOptions: options =>
{
options.RequireHttpsMetadata = false;
options.Audience = "weather.api";
});
builder.Services.AddAuthorizationBuilder();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseExceptionHandler();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
string[] summaries = ["Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"];
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.RequireAuthorization();
app.MapDefaultEndpoints();
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
上記の ASP.NET Core Minimal API Program
クラスは、次の例を示しています。
- AddAuthentication API を使用して DI コンテナーに認証サービスを追加する。
-
AddKeycloakJwtBearer API を使用した JWT ベアラー認証の追加と構成:
-
keycloak
としてのserviceName
。 -
WeatherShop
としてのrealm
。 -
options
はAudience
をweather.api
に設定し、RequireHttpsMetadata
をfalse
に設定します。
-
- AddAuthorizationBuilder API を使用して、承認サービスを DI コンテナーに追加します。
-
RequireAuthorization API を呼び出して、
/weatherforecast
エンドポイントでの承認を要求します。
完全な作業サンプルについては、「.NET Aspire プレイグラウンド: Keycloak 統合」を参照してください。
OpenId Connect 認証を追加する
API を使用するプロジェクトの Program.cs ファイル (たとえば、Blazor) で、接続名、領域、必要な OpenId Connect オプションを使用して、AddKeycloakOpenIdConnect 拡張メソッドを呼び出して OpenId Connect 認証を追加します。
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddKeycloakOpenIdConnect(
serviceName: "keycloak",
realm: "api",
options =>
{
options.ClientId = "StoreWeb";
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("store:all");
});
Action<OpenIdConnectOptions>? configureOptions
デリゲートを使用して、他の多くのオプションを設定できます。
OpenId Connect 認証の例
OpenId Connect 認証をさらに例示するには、次の例を考えてみましょう。
using System.IdentityModel.Tokens.Jwt;
using AspireApp.Web;
using AspireApp.Web.Components;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
var builder = WebApplication.CreateBuilder(args);
// Add service defaults & Aspire client integrations.
builder.AddServiceDefaults();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddOutputCache();
builder.Services.AddHttpContextAccessor()
.AddTransient<AuthorizationHandler>();
builder.Services.AddHttpClient<WeatherApiClient>(client =>
{
// This URL uses "https+http://" to indicate HTTPS is preferred over HTTP.
// Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes.
client.BaseAddress = new("https+http://apiservice");
})
.AddHttpMessageHandler<AuthorizationHandler>();
var oidcScheme = OpenIdConnectDefaults.AuthenticationScheme;
builder.Services.AddAuthentication(oidcScheme)
.AddKeycloakOpenIdConnect("keycloak", realm: "WeatherShop", oidcScheme, options =>
{
options.ClientId = "WeatherWeb";
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("weather:all");
options.RequireHttpsMetadata = false;
options.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
options.SaveTokens = true;
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
builder.Services.AddCascadingAuthenticationState();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAntiforgery();
app.UseOutputCache();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.MapDefaultEndpoints();
app.MapLoginAndLogout();
app.Run();
上記の ASP.NET CoreBlazorProgram
クラス:
-
AddHttpContextAccessor API を使用して DI コンテナーに
HttpContextAccessor
を追加します。 -
AddTransient<TService>(IServiceCollection) API を使用して、DI コンテナーに一時的なサービスとしてカスタム
AuthorizationHandler
を追加します。 API を用いて サービスに を追加し、サービス検出 セマンティクスを用いて のベースアドレスを構成し、最終的に に解決します。 -
AddHttpMessageHandler API への呼び出しをチェーンして、
HttpClient
パイプラインにAuthorizationHandler
を追加します。
-
AddHttpMessageHandler API への呼び出しをチェーンして、
- OpenId Connect の既定の認証スキームを渡す AddAuthentication API を使用して、DI コンテナーに認証サービスを追加します。
-
AddKeycloakOpenIdConnect を呼び出し、
keycloak
としてserviceName
を構成し、realm
をWeatherShop
として、さまざまな設定を持つoptions
オブジェクトを構成します。 - AddCascadingAuthenticationState API を使用して、Blazor アプリにカスケード認証状態を追加します。
最後の引き出しは、Blazor アプリにログインルートとログアウト ルートを追加する MapLoginAndLogout
拡張メソッドです。 これは次のように定義されます。
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http.HttpResults;
namespace AspireApp.Web;
internal static class LoginLogoutEndpointRouteBuilderExtensions
{
internal static IEndpointConventionBuilder MapLoginAndLogout(
this IEndpointRouteBuilder endpoints)
{
var group = endpoints.MapGroup("authentication");
group.MapGet(pattern: "/login", OnLogin).AllowAnonymous();
group.MapPost(pattern: "/logout", OnLogout);
return group;
}
static ChallengeHttpResult OnLogin() =>
TypedResults.Challenge(properties: new AuthenticationProperties
{
RedirectUri = "/"
});
static SignOutHttpResult OnLogout() =>
TypedResults.SignOut(properties: new AuthenticationProperties
{
RedirectUri = "/"
},
[
CookieAuthenticationDefaults.AuthenticationScheme,
OpenIdConnectDefaults.AuthenticationScheme
]);
}
上記のコード:
-
authentication
ルートのグループをマップし、login
ルートとlogout
ルートの 2 つのエンドポイントをマップします。-
GET
要求を、ハンドラーがOnLogin
メソッドである/login
ルートにマップします。これは匿名エンドポイントです。 -
GET
要求を、OnLogout
メソッドであるハンドラーの/logout
ルートにマップします。
-
AuthorizationHandler
は、Bearer
トークンを HttpClient
要求に追加するカスタム ハンドラーです。 ハンドラーは次のように定義されます。
using Microsoft.AspNetCore.Authentication;
using System.Net.Http.Headers;
namespace AspireApp.Web;
public class AuthorizationHandler(IHttpContextAccessor httpContextAccessor)
: DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var httpContext = httpContextAccessor.HttpContext ??
throw new InvalidOperationException("""
No HttpContext available from the IHttpContextAccessor.
""");
var accessToken = await httpContext.GetTokenAsync("access_token");
if (!string.IsNullOrWhitespace(accessToken))
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}
return await base.SendAsync(request, cancellationToken);
}
}
上記のコード:
- DelegatingHandler クラスのサブクラスです。
- プライマリ コンストラクターに
IHttpContextAccessor
サービスを挿入します。 -
SendAsync
メソッドをオーバーライドして、HttpClient
要求にBearer
トークンを追加します。-
access_token
はHttpContext
から取得され、Authorization
ヘッダーに追加されます。
-
認証フローを視覚化するには、次のシーケンス図を検討してください。
完全な作業サンプルについては、「.NET Aspire プレイグラウンド: Keycloak 統合」を参照してください。
関連項目
.NET Aspire