.NET Aspire Keycloak integrering (förhandsversion)
omfattar:Hostingintegrering och
Client integration
Keycloak är en identitets- och åtkomsthanteringslösning med öppen källkod som riktar sig till moderna program och tjänster. Med integreringen .NET AspireKeycloak kan du ansluta till befintliga Keycloak-instanser eller skapa nya instanser från .NET med quay.io/keycloak/keycloak
containeravbildningen.
Hostingtjänstintegration
.NET Aspire Keycloak-integrationen modellerar servern som KeycloakResource-typen. Om du vill komma åt dessa typer och API:er lägger du till 📦Aspire. Gästfrihet.Keycloak NuGet-paket i appvärd projekt.
dotnet add package Aspire.Hosting.Keycloak --prerelease
Mer information finns i dotnet add package or Manage package dependencies in .NET applications.
Lägga till Keycloak resurs
I appvärdprojektet anropar du AddKeycloak för att lägga till och returnera en Keycloak resursbyggare. Länka ett anrop till den returnerade resursbyggaren för att konfigurera 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...
Tips
För lokal utveckling använder du en stabil port för den Keycloak resursen (8080
i föregående exempel). Det kan vara vilken port som helst, men det bör vara stabilt för att undvika problem med webbläsarcookies som bevarar OIDC-token (som inkluderar utfärdarens URL, med port) utöver livslängden för appvärd.
När .NET.NET Aspire lägger till en containeravbildning i apputrymmet, som du ser i föregående exempel med quay.io/keycloak/keycloak
containeravbildningen, skapar den en ny Keycloak instans på din lokala dator. Den Keycloak resursen innehåller standardautentiseringsuppgifter:
-
KEYCLOAK_ADMIN
: Värdetadmin
. -
KEYCLOAK_ADMIN_PASSWORD
: Slumpmässigpassword
genereras med hjälp av metoden CreateDefaultPasswordParameter.
När appvärden körs lagras lösenordet i appvärdens hemliga arkiv. Det läggs till i avsnittet Parameters
, till exempel:
{
"Parameters:keycloak-password": "<THE_GENERATED_PASSWORD>"
}
Namnet på parametern är keycloak-password
, men egentligen är det bara att formatera resursnamnet med ett -password
suffix. Mer information finns i Säker lagring av apphemligheter under utveckling i ASP.NET Core och Lägg till Keycloak resurs.
Metoden WithReference konfigurerar en anslutning i ExampleProject
med namnet keycloak
och WaitFor instruerar appvärden att inte starta den beroende tjänsten förrän keycloak
resursen är klar.
Tips
Om du hellre vill ansluta till en befintlig Keycloak instans anropar du AddConnectionString i stället. Mer information finns i Referera till befintliga resurser.
Lägga till Keycloak resurs med datavolym
Om du vill lägga till en datavolym i resursen Keycloak anropar du metoden WithDataVolume på den Keycloak resursen:
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...
Datavolymen används för att bevara Keycloak data utanför containerns livscykel. Datavolymen monteras på sökvägen /opt/keycloak/data
i containern Keycloak, och när en name
-parameter inte anges, genereras namnet slumpmässigt. Mer information om datavolymer och detaljer om varför de föredras framför bindmonteringarfinns i Docker dokumentationen: Volymer.
Varning
Administratörsautentiseringsuppgifterna lagras i datavolymen. När du använder en datavolym och om autentiseringsuppgifterna ändras fungerar det inte förrän du tar bort volymen.
Lägg till Keycloak resurs med databindningsmontering
För att lägga till en databindning till Keycloak-resursen, anropar du metoden 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...
Viktig
Data bindningsmonteringar har begränsade funktioner jämfört med volymer, vilket ger bättre prestanda, portabilitet och säkerhet, vilket gör dem mer lämpliga för produktionsmiljöer. Bindningsmonteringar tillåter dock direkt åtkomst och ändring av filer i värdsystemet, perfekt för utveckling och testning där realtidsändringar behövs.
Data-bind-monteringarna använder värddatorns filsystem för att behålla Keycloak-data mellan omstarter av containrar. Databindningsmonteringen monteras på sökvägen C:\Keycloak\Data
i Windows (eller /Keycloak/Data
på Unix) på värddatorn i Keycloak-containern. Mer information om databindningsmonteringar finns i Docker dokument: Bind monteringar.
Lägga till Keycloak resurs med parametrar
När du uttryckligen vill ange administratörens användarnamn och lösenord som används av containeravbildningen kan du ange dessa autentiseringsuppgifter som parametrar. Tänk dig följande alternativa exempel:
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...
Parametrarna username
och password
tillhandahålls vanligtvis som miljövariabler eller hemligheter. Parametrarna används för att ange miljövariablerna KEYCLOAK_ADMIN
och KEYCLOAK_ADMIN_PASSWORD
i containern. Mer information om hur du tillhandahåller parametrar finns i Externa parametrar.
Lägg till Keycloak resurs med sfärimport
Om du vill importera en sfär till Keycloakanropar du metoden 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();
Sfärimportfilerna monteras på /opt/keycloak/data/import
i Keycloak-containern. Sfärimportfiler är JSON filer som representerar sfärkonfigurationen. Mer information om sfärimport finns i Keycloak dokument: Importera en sfär.
Till exempel kan följande JSON-fil läggas till i värdprojektet för appen i en /Realms-mapp för att användas som en konfigurationsfil för källan.
Växla sfär JSON exempel.
{
"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": []
}
}
Genomföra hälsokontroller för systemintegrering
Keycloak värdintegrering stöder för närvarande inte hälsokontroller och lägger inte heller till dem automatiskt.
Client integrering
Kom igång med .NET AspireKeycloak-klientintegrering genom att installera 📦Aspire.Keycloak. Autentisering NuGet-paket i det klientkrävande projektet, d.v.s. projektet för programmet som använder Keycloak-klienten. Keycloak-klientintegrering registrerar JwtBearer- och OpenId Connect-autentiseringshanterare i DI-containern för anslutning till en Keycloak.
dotnet add package Aspire.Keycloak.Authentication
Lägga till JWT-ägarautentisering
I Program.cs-filen för ditt ASP.NET Core API-projekt anropar du metoden AddKeycloakJwtBearer-tillägg för att lägga till JwtBearer-autentisering med hjälp av ett anslutningsnamn, sfär och alla nödvändiga JWT-ägaralternativ:
builder.Services.AddAuthentication()
.AddKeycloakJwtBearer(
serviceName: "keycloak",
realm: "api",
options =>
{
options.Audience = "store.api";
});
Du kan ange många andra alternativ via Action<JwtBearerOptions> configureOptions
delegat.
Exempel på JWT-ägarautentisering
Tänk på följande exempel för att ytterligare exemplifiera JWT-ägarautentiseringen:
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);
}
Föregående ASP.NET Core Minimal API-Program
-klass visar:
- Lägga till autentiseringstjänster i DI-containern med AddAuthentication-API:et.
- Lägga till JWT-ägarautentisering med AddKeycloakJwtBearer-API:et och konfigurera:
-
serviceName
somkeycloak
. -
realm
somWeatherShop
. -
options
medAudience
inställt påweather.api
och ställer inRequireHttpsMetadata
tillfalse
.
-
- Lägger till auktoriseringstjänster i DI-containern med AddAuthorizationBuilder-API:et.
- Anropar RequireAuthorization-API:et för att kräva auktorisering på
/weatherforecast
slutpunkten.
Ett fullständigt arbetsexempel finns i .NET Aspire lekplats: Keycloak integration.
Lägga till OpenId Connect-autentisering
I Program.cs-filen i ditt API-användande projekt (till exempel Blazor) använder du AddKeycloakOpenIdConnect-tillägget för att lägga till OpenId Connect-autentisering med hjälp av ett anslutningsnamn, en domän och alla nödvändiga OpenId Connect-alternativ.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddKeycloakOpenIdConnect(
serviceName: "keycloak",
realm: "api",
options =>
{
options.ClientId = "StoreWeb";
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("store:all");
});
Du kan ange många andra alternativ via Action<OpenIdConnectOptions>? configureOptions
delegat.
OpenId Connect-autentiseringsexempel
Tänk på följande exempel för att ytterligare exemplifiera OpenId Connect-autentiseringen:
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();
Föregående ASP.NET CoreBlazorProgram
-klass:
- Lägger till
HttpContextAccessor
i DI-containern med AddHttpContextAccessor-API:et. - Lägger till en anpassad
AuthorizationHandler
som en tillfällig tjänst i DI-containern med AddTransient<TService>(IServiceCollection)-API:et. - Lägger till en HttpClient till
WeatherApiClient
-tjänsten med AddHttpClient<TClient>(IServiceCollection)-API:et och konfigurerar basadressen med tjänstidentifiering semantik som matcharapiservice
.- Kedjar ett anrop till AddHttpMessageHandler-API:et för att lägga till en
AuthorizationHandler
iHttpClient
pipeline.
- Kedjar ett anrop till AddHttpMessageHandler-API:et för att lägga till en
- Lägger till autentiseringstjänster i DI-containern med AddAuthentication-API:et som använder standardautentiseringsschemat för OpenId Connect.
- Anropar AddKeycloakOpenIdConnect och konfigurerar
serviceName
somkeycloak
,realm
somWeatherShop
ochoptions
-objektet med olika inställningar. - Lägger till sammanhängande autentiseringstillstånd i Blazor-appen med AddCascadingAuthenticationState-API:et.
Den sista utropet är MapLoginAndLogout
-tilläggsmetoden som lägger till inloggnings- och utloggningsrutter till Blazor-applikationen. Detta definieras på följande sätt:
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
]);
}
Föregående kod:
- Kartlägger en grupp för rutt
authentication
och kartlägger två slutpunkter för rutternalogin
ochlogout
:- Mappar en
GET
-begäran till/login
-rutten vars hanterare ärOnLogin
-metoden – detta är ett anonymt slutpunkt. - Mappar en
GET
-begäran till den/logout
-rutt vars hanterare ärOnLogout
-metoden.
- Mappar en
AuthorizationHandler
är en anpassad hanterare som lägger till Bearer
token i HttpClient
begäran. Hanteraren definieras på följande sätt:
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);
}
}
Föregående kod:
- Är en underklass av klassen DelegatingHandler.
- Injicerar tjänsten
IHttpContextAccessor
i den primära konstruktorn. - Åsidosätter metoden
SendAsync
för att lägga tillBearer
-symbol tillHttpClient
-begäran:-
access_token
hämtas frånHttpContext
och läggs till iAuthorization
-huvudet.
-
Tänk på följande sekvensdiagram för att visualisera autentiseringsflödet:
Ett fullständigt arbetsexempel finns i .NET Aspire lekplats: Keycloak integration.
Se även
.NET Aspire