master 4110f38c4a55 cached
13 files
80.5 KB
26.0k tokens
18 symbols
1 requests
Download .txt
Repository: thomasdarimont/spring-boot-2-keycloak-oauth-example
Branch: master
Commit: 4110f38c4a55
Files: 13
Total size: 80.5 KB

Directory structure:
gitextract_swett08m/

├── .gitignore
├── .mvn/
│   └── wrapper/
│       ├── maven-wrapper.jar
│       └── maven-wrapper.properties
├── demo-realm.json
├── mvnw
├── mvnw.cmd
├── pom.xml
├── readme.md
└── src/
    └── main/
        ├── java/
        │   └── demo/
        │       └── SpringBoot2App.java
        └── resources/
            ├── application.yml
            └── templates/
                ├── admin.html
                ├── app.html
                └── index.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
target/
!.mvn/wrapper/maven-wrapper.jar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/

================================================
FILE: .mvn/wrapper/maven-wrapper.properties
================================================
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip


================================================
FILE: demo-realm.json
================================================
{
  "id" : "demo",
  "realm" : "demo",
  "notBefore" : 0,
  "revokeRefreshToken" : false,
  "refreshTokenMaxReuse" : 0,
  "accessTokenLifespan" : 300,
  "accessTokenLifespanForImplicitFlow" : 900,
  "ssoSessionIdleTimeout" : 1800,
  "ssoSessionMaxLifespan" : 36000,
  "offlineSessionIdleTimeout" : 2592000,
  "accessCodeLifespan" : 60,
  "accessCodeLifespanUserAction" : 300,
  "accessCodeLifespanLogin" : 1800,
  "actionTokenGeneratedByAdminLifespan" : 43200,
  "actionTokenGeneratedByUserLifespan" : 300,
  "enabled" : true,
  "sslRequired" : "external",
  "registrationAllowed" : false,
  "registrationEmailAsUsername" : false,
  "rememberMe" : false,
  "verifyEmail" : false,
  "loginWithEmailAllowed" : true,
  "duplicateEmailsAllowed" : false,
  "resetPasswordAllowed" : false,
  "editUsernameAllowed" : false,
  "bruteForceProtected" : false,
  "permanentLockout" : false,
  "maxFailureWaitSeconds" : 900,
  "minimumQuickLoginWaitSeconds" : 60,
  "waitIncrementSeconds" : 60,
  "quickLoginCheckMilliSeconds" : 1000,
  "maxDeltaTimeSeconds" : 43200,
  "failureFactor" : 30,
  "roles" : {
    "realm" : [ {
      "id" : "9cec708f-b60c-4e72-87bd-bd6cc270804f",
      "name" : "offline_access",
      "description" : "${role_offline-access}",
      "scopeParamRequired" : true,
      "composite" : false,
      "clientRole" : false,
      "containerId" : "demo"
    }, {
      "id" : "b377ec00-d24e-481c-88d1-fc236fcbb4f8",
      "name" : "uma_authorization",
      "description" : "${role_uma_authorization}",
      "scopeParamRequired" : false,
      "composite" : false,
      "clientRole" : false,
      "containerId" : "demo"
    } ],
    "client" : {
      "realm-management" : [ {
        "id" : "e20d8308-6e6e-4814-8b6c-f31e429d83d8",
        "name" : "query-clients",
        "description" : "${role_query-clients}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "b64456f6-a12d-455d-8f91-5b2a508d1326",
        "name" : "view-identity-providers",
        "description" : "${role_view-identity-providers}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "968aa5a6-220f-4c73-a1d9-d1eb4b3f7f20",
        "name" : "query-groups",
        "description" : "${role_query-groups}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "54db3285-f76c-462f-9dea-3f0da29a8277",
        "name" : "view-events",
        "description" : "${role_view-events}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "f63004bf-394b-426f-b609-19ca807f3a57",
        "name" : "manage-users",
        "description" : "${role_manage-users}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "273b678a-2018-4480-9007-b0b5d318019e",
        "name" : "query-users",
        "description" : "${role_query-users}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "b0bcfe2c-e426-4cc8-8161-f6608203409b",
        "name" : "view-users",
        "description" : "${role_view-users}",
        "scopeParamRequired" : false,
        "composite" : true,
        "composites" : {
          "client" : {
            "realm-management" : [ "query-groups", "query-users" ]
          }
        },
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "4f2d2465-9e75-4975-8748-ec2bbb2f1b96",
        "name" : "query-realms",
        "description" : "${role_query-realms}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "65c72650-d874-4a6b-a065-4558a3e2fc6a",
        "name" : "create-client",
        "description" : "${role_create-client}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "a56996bc-9589-476b-9e54-88b5e6355fca",
        "name" : "manage-clients",
        "description" : "${role_manage-clients}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "6e8e2d8d-1632-4893-8428-3ec4c438bead",
        "name" : "view-clients",
        "description" : "${role_view-clients}",
        "scopeParamRequired" : false,
        "composite" : true,
        "composites" : {
          "client" : {
            "realm-management" : [ "query-clients" ]
          }
        },
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "25c953c3-a411-4237-8501-7b8ebef5988f",
        "name" : "manage-realm",
        "description" : "${role_manage-realm}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "dc1a53ec-d0e1-441f-8e72-8ca411ab21a0",
        "name" : "view-authorization",
        "description" : "${role_view-authorization}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "30bbf430-98a6-46d5-a25c-48992aebd848",
        "name" : "realm-admin",
        "description" : "${role_realm-admin}",
        "scopeParamRequired" : false,
        "composite" : true,
        "composites" : {
          "client" : {
            "realm-management" : [ "query-clients", "query-groups", "view-identity-providers", "view-events", "manage-users", "query-users", "query-realms", "view-users", "create-client", "manage-clients", "view-clients", "manage-realm", "view-authorization", "manage-events", "impersonation", "manage-authorization", "view-realm", "manage-identity-providers" ]
          }
        },
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "2f93f784-ece8-4205-a9c2-b933b6beee09",
        "name" : "manage-events",
        "description" : "${role_manage-events}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "eb6ab687-958a-4c24-a97d-569e31101c41",
        "name" : "manage-authorization",
        "description" : "${role_manage-authorization}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "e4d149d9-5c8e-4f1c-9a40-ac371aaf3794",
        "name" : "impersonation",
        "description" : "${role_impersonation}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "3f9d491f-7df0-4f91-ab0d-5f5531b41f9d",
        "name" : "view-realm",
        "description" : "${role_view-realm}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      }, {
        "id" : "11ba2522-4090-431b-9842-0e9f31884d0a",
        "name" : "manage-identity-providers",
        "description" : "${role_manage-identity-providers}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
      } ],
      "security-admin-console" : [ ],
      "admin-cli" : [ ],
      "app-demo" : [ {
        "id" : "57b84603-ceef-4a48-bd08-f46467eb7bd9",
        "name" : "admin",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "ec2975dc-bde7-4012-89c4-06a499c00235"
      }, {
        "id" : "754c1364-9444-4477-bcc1-b07794bee2fc",
        "name" : "user",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "ec2975dc-bde7-4012-89c4-06a499c00235"
      } ],
      "broker" : [ {
        "id" : "f08f6cf6-09ed-41f6-9c05-164dc8f8ab5e",
        "name" : "read-token",
        "description" : "${role_read-token}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "0536d12c-2c36-444a-898b-ed7b527aac76"
      } ],
      "account" : [ {
        "id" : "c4cf29c5-3375-45d1-acd2-5962af1c733a",
        "name" : "manage-account",
        "description" : "${role_manage-account}",
        "scopeParamRequired" : false,
        "composite" : true,
        "composites" : {
          "client" : {
            "account" : [ "manage-account-links" ]
          }
        },
        "clientRole" : true,
        "containerId" : "2e441b12-8370-49b8-b8aa-2c7546144b4e"
      }, {
        "id" : "5d703753-792e-4167-ad2b-c5b7f6a959d7",
        "name" : "view-profile",
        "description" : "${role_view-profile}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "2e441b12-8370-49b8-b8aa-2c7546144b4e"
      }, {
        "id" : "8eb0ae88-2819-47ab-9a93-6ff34b43ae88",
        "name" : "manage-account-links",
        "description" : "${role_manage-account-links}",
        "scopeParamRequired" : false,
        "composite" : false,
        "clientRole" : true,
        "containerId" : "2e441b12-8370-49b8-b8aa-2c7546144b4e"
      } ]
    }
  },
  "groups" : [ ],
  "defaultRoles" : [ "offline_access", "uma_authorization" ],
  "requiredCredentials" : [ "password" ],
  "otpPolicyType" : "totp",
  "otpPolicyAlgorithm" : "HmacSHA1",
  "otpPolicyInitialCounter" : 0,
  "otpPolicyDigits" : 6,
  "otpPolicyLookAheadWindow" : 1,
  "otpPolicyPeriod" : 30,
  "otpSupportedApplications" : [ "FreeOTP", "Google Authenticator" ],
  "users" : [ {
    "id" : "8d7a7207-94c0-4ba7-ac3a-efb79412dd44",
    "createdTimestamp" : 1523988975613,
    "username" : "admin",
    "enabled" : true,
    "totp" : false,
    "emailVerified" : false,
    "firstName" : "Arno",
    "lastName" : "Admin",
    "email" : "tom+admin@localhost",
    "credentials" : [ {
      "type" : "password",
      "hashedSaltedValue" : "ZcC45qA9JiFQYuJau1w/pxfBmZusDDoCO0Sx4z+uFWdE4CA1FUibOqpqHh21GwRKcdRSseqrBBaaPbBznIWYRQ==",
      "salt" : "sTMbn/fDpC/KX549o9XoHg==",
      "hashIterations" : 27500,
      "counter" : 0,
      "algorithm" : "pbkdf2-sha256",
      "digits" : 0,
      "period" : 0,
      "createdDate" : 1523988982527,
      "config" : { }
    } ],
    "disableableCredentialTypes" : [ "password" ],
    "requiredActions" : [ ],
    "realmRoles" : [ "offline_access", "uma_authorization" ],
    "clientRoles" : {
      "app-demo" : [ "admin", "user" ],
      "account" : [ "manage-account", "view-profile" ]
    },
    "notBefore" : 0,
    "groups" : [ ]
  }, {
    "id" : "91591318-6c82-4250-b6fb-9a5e257959a5",
    "createdTimestamp" : 1523983635756,
    "username" : "tester",
    "enabled" : true,
    "totp" : false,
    "emailVerified" : false,
    "firstName" : "Theo",
    "lastName" : "Tester",
    "email" : "tom+test@localhost",
    "credentials" : [ {
      "type" : "password",
      "hashedSaltedValue" : "h/aCiQS3fdB/euTSwOz/ww/+L0b6c9WGsRsMMSPr899rQIFLlIhjWjAgA9BbRAKsSLfo+nsNUKaXGfhwgi2r7g==",
      "salt" : "W3mOjqoG8mctglGSgbYSKQ==",
      "hashIterations" : 27500,
      "counter" : 0,
      "algorithm" : "pbkdf2-sha256",
      "digits" : 0,
      "period" : 0,
      "createdDate" : 1523983645059,
      "config" : { }
    } ],
    "disableableCredentialTypes" : [ "password" ],
    "requiredActions" : [ ],
    "realmRoles" : [ "offline_access", "uma_authorization" ],
    "clientRoles" : {
      "app-demo" : [ "user" ],
      "account" : [ "manage-account", "view-profile" ]
    },
    "notBefore" : 0,
    "groups" : [ ]
  } ],
  "clients" : [ {
    "id" : "2e441b12-8370-49b8-b8aa-2c7546144b4e",
    "clientId" : "account",
    "name" : "${client_account}",
    "baseUrl" : "/auth/realms/demo/account",
    "surrogateAuthRequired" : false,
    "enabled" : true,
    "clientAuthenticatorType" : "client-secret",
    "secret" : "85e4ed69-3da1-4d34-ba4e-31980b4b386d",
    "defaultRoles" : [ "view-profile", "manage-account" ],
    "redirectUris" : [ "/auth/realms/demo/account/*" ],
    "webOrigins" : [ ],
    "notBefore" : 0,
    "bearerOnly" : false,
    "consentRequired" : false,
    "standardFlowEnabled" : true,
    "implicitFlowEnabled" : false,
    "directAccessGrantsEnabled" : false,
    "serviceAccountsEnabled" : false,
    "publicClient" : false,
    "frontchannelLogout" : false,
    "protocol" : "openid-connect",
    "attributes" : { },
    "fullScopeAllowed" : false,
    "nodeReRegistrationTimeout" : 0,
    "protocolMappers" : [ {
      "id" : "61173bf1-f182-4c08-81f1-45ded5285a96",
      "name" : "given name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${givenName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "firstName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "given_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "3fc7edb3-23e1-4211-9a71-61700c849841",
      "name" : "family name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${familyName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "lastName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "family_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "33bcaadd-4cae-44fd-8f53-cfbb9b1804a3",
      "name" : "email",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${email}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "email",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "email",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "b7ea4f28-5d0c-4ec3-b03f-bef776943c65",
      "name" : "username",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${username}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "username",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "preferred_username",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "493cb2a0-3b7d-46de-9aa4-e9b36e9b75c5",
      "name" : "role list",
      "protocol" : "saml",
      "protocolMapper" : "saml-role-list-mapper",
      "consentRequired" : false,
      "config" : {
        "single" : "false",
        "attribute.nameformat" : "Basic",
        "attribute.name" : "Role"
      }
    }, {
      "id" : "f2e9d26c-4703-4fac-b5d5-cbbb8cbf9fbc",
      "name" : "full name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-full-name-mapper",
      "consentRequired" : true,
      "consentText" : "${fullName}",
      "config" : {
        "id.token.claim" : "true",
        "access.token.claim" : "true"
      }
    } ],
    "useTemplateConfig" : false,
    "useTemplateScope" : false,
    "useTemplateMappers" : false
  }, {
    "id" : "c0d68b59-146c-462e-910d-eae82c190c61",
    "clientId" : "admin-cli",
    "name" : "${client_admin-cli}",
    "surrogateAuthRequired" : false,
    "enabled" : true,
    "clientAuthenticatorType" : "client-secret",
    "secret" : "e4491867-8a42-4ca4-93ee-34a898ea6775",
    "redirectUris" : [ ],
    "webOrigins" : [ ],
    "notBefore" : 0,
    "bearerOnly" : false,
    "consentRequired" : false,
    "standardFlowEnabled" : false,
    "implicitFlowEnabled" : false,
    "directAccessGrantsEnabled" : true,
    "serviceAccountsEnabled" : false,
    "publicClient" : true,
    "frontchannelLogout" : false,
    "protocol" : "openid-connect",
    "attributes" : { },
    "fullScopeAllowed" : false,
    "nodeReRegistrationTimeout" : 0,
    "protocolMappers" : [ {
      "id" : "e005a327-9dcb-447d-80c2-f7c668d0afaa",
      "name" : "full name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-full-name-mapper",
      "consentRequired" : true,
      "consentText" : "${fullName}",
      "config" : {
        "id.token.claim" : "true",
        "access.token.claim" : "true"
      }
    }, {
      "id" : "a4cab9da-4684-4bdb-8351-abf2d9428845",
      "name" : "given name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${givenName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "firstName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "given_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "b2fc3109-62de-4b87-8c31-29e895329f93",
      "name" : "family name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${familyName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "lastName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "family_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "90622937-00bc-4e2e-a5d6-3f573712b2d2",
      "name" : "username",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${username}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "username",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "preferred_username",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "4960d696-da1f-4fd2-8e15-49cdad809b03",
      "name" : "email",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${email}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "email",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "email",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "c175c2f3-d399-4171-a46a-ac74a5b835f0",
      "name" : "role list",
      "protocol" : "saml",
      "protocolMapper" : "saml-role-list-mapper",
      "consentRequired" : false,
      "config" : {
        "single" : "false",
        "attribute.nameformat" : "Basic",
        "attribute.name" : "Role"
      }
    } ],
    "useTemplateConfig" : false,
    "useTemplateScope" : false,
    "useTemplateMappers" : false
  }, {
    "id" : "ec2975dc-bde7-4012-89c4-06a499c00235",
    "clientId" : "app-demo",
    "baseUrl" : "http://localhost:8082/",
    "surrogateAuthRequired" : false,
    "enabled" : true,
    "clientAuthenticatorType" : "client-secret",
    "secret" : "e3f519b4-0272-4261-9912-8b7453ac4ecd",
    "redirectUris" : [ "http://localhost:8082/*" ],
    "webOrigins" : [ "http://localhost:8082" ],
    "notBefore" : 0,
    "bearerOnly" : false,
    "consentRequired" : false,
    "standardFlowEnabled" : true,
    "implicitFlowEnabled" : false,
    "directAccessGrantsEnabled" : true,
    "serviceAccountsEnabled" : false,
    "publicClient" : false,
    "frontchannelLogout" : false,
    "protocol" : "openid-connect",
    "attributes" : {
      "saml.assertion.signature" : "false",
      "saml.force.post.binding" : "false",
      "saml.multivalued.roles" : "false",
      "saml.encrypt" : "false",
      "saml_force_name_id_format" : "false",
      "saml.client.signature" : "false",
      "saml.authnstatement" : "false",
      "saml.server.signature" : "false",
      "saml.server.signature.keyinfo.ext" : "false",
      "saml.onetimeuse.condition" : "false"
    },
    "fullScopeAllowed" : true,
    "nodeReRegistrationTimeout" : -1,
    "protocolMappers" : [ {
      "id" : "f632a9a7-5cff-4254-9941-82fabfdb3216",
      "name" : "role list",
      "protocol" : "saml",
      "protocolMapper" : "saml-role-list-mapper",
      "consentRequired" : false,
      "config" : {
        "single" : "false",
        "attribute.nameformat" : "Basic",
        "attribute.name" : "Role"
      }
    }, {
      "id" : "488d9ab7-7585-41dc-9d09-dd6d639b7a24",
      "name" : "username",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${username}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "username",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "preferred_username",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "de28c7ae-a613-4f9d-8edb-1b9aa507efb9",
      "name" : "email",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${email}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "email",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "email",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "6611aecf-daad-4ad2-aa74-c33de47037b0",
      "name" : "full name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-full-name-mapper",
      "consentRequired" : true,
      "consentText" : "${fullName}",
      "config" : {
        "id.token.claim" : "true",
        "access.token.claim" : "true"
      }
    }, {
      "id" : "cb5a11ce-3311-4a78-9061-e6221184b6f5",
      "name" : "given name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${givenName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "firstName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "given_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "4ec046bf-9c35-44ac-9395-fcda434fc061",
      "name" : "family name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${familyName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "lastName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "family_name",
        "jsonType.label" : "String"
      }
    } ],
    "useTemplateConfig" : false,
    "useTemplateScope" : false,
    "useTemplateMappers" : false
  }, {
    "id" : "0536d12c-2c36-444a-898b-ed7b527aac76",
    "clientId" : "broker",
    "name" : "${client_broker}",
    "surrogateAuthRequired" : false,
    "enabled" : true,
    "clientAuthenticatorType" : "client-secret",
    "secret" : "577625be-1736-4bee-9bb2-608aff465c64",
    "redirectUris" : [ ],
    "webOrigins" : [ ],
    "notBefore" : 0,
    "bearerOnly" : false,
    "consentRequired" : false,
    "standardFlowEnabled" : true,
    "implicitFlowEnabled" : false,
    "directAccessGrantsEnabled" : false,
    "serviceAccountsEnabled" : false,
    "publicClient" : false,
    "frontchannelLogout" : false,
    "protocol" : "openid-connect",
    "attributes" : { },
    "fullScopeAllowed" : false,
    "nodeReRegistrationTimeout" : 0,
    "protocolMappers" : [ {
      "id" : "5f5e550c-ff29-482d-bb1f-0215d6bf081d",
      "name" : "family name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${familyName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "lastName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "family_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "9239d7be-795f-4307-b0fe-ae0635fc367f",
      "name" : "full name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-full-name-mapper",
      "consentRequired" : true,
      "consentText" : "${fullName}",
      "config" : {
        "id.token.claim" : "true",
        "access.token.claim" : "true"
      }
    }, {
      "id" : "c7be1c7e-a0d2-4fe3-869c-de00d694f067",
      "name" : "email",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${email}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "email",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "email",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "e0c76ba5-d83d-4366-9b16-7b334fa587d4",
      "name" : "role list",
      "protocol" : "saml",
      "protocolMapper" : "saml-role-list-mapper",
      "consentRequired" : false,
      "config" : {
        "single" : "false",
        "attribute.nameformat" : "Basic",
        "attribute.name" : "Role"
      }
    }, {
      "id" : "d97fa215-8d04-466b-8c19-a7c5f14ed1fa",
      "name" : "username",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${username}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "username",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "preferred_username",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "b5359a60-d80b-4c5d-aa7c-ff3d1959aa9b",
      "name" : "given name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${givenName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "firstName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "given_name",
        "jsonType.label" : "String"
      }
    } ],
    "useTemplateConfig" : false,
    "useTemplateScope" : false,
    "useTemplateMappers" : false
  }, {
    "id" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd",
    "clientId" : "realm-management",
    "name" : "${client_realm-management}",
    "surrogateAuthRequired" : false,
    "enabled" : true,
    "clientAuthenticatorType" : "client-secret",
    "secret" : "05f5e2a2-83c9-45be-bc8b-7d9c2a924ed4",
    "redirectUris" : [ ],
    "webOrigins" : [ ],
    "notBefore" : 0,
    "bearerOnly" : true,
    "consentRequired" : false,
    "standardFlowEnabled" : true,
    "implicitFlowEnabled" : false,
    "directAccessGrantsEnabled" : false,
    "serviceAccountsEnabled" : false,
    "publicClient" : false,
    "frontchannelLogout" : false,
    "protocol" : "openid-connect",
    "attributes" : { },
    "fullScopeAllowed" : false,
    "nodeReRegistrationTimeout" : 0,
    "protocolMappers" : [ {
      "id" : "b699f558-b852-4013-a8c2-177abf9a8353",
      "name" : "full name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-full-name-mapper",
      "consentRequired" : true,
      "consentText" : "${fullName}",
      "config" : {
        "id.token.claim" : "true",
        "access.token.claim" : "true"
      }
    }, {
      "id" : "1377d3f0-8587-4458-8252-1f740f00dbe1",
      "name" : "email",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${email}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "email",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "email",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "ca0e2b5c-6580-4949-80bd-fb3b87a0c7b5",
      "name" : "role list",
      "protocol" : "saml",
      "protocolMapper" : "saml-role-list-mapper",
      "consentRequired" : false,
      "config" : {
        "single" : "false",
        "attribute.nameformat" : "Basic",
        "attribute.name" : "Role"
      }
    }, {
      "id" : "101f9558-3e9c-4f34-b11b-b7e9f6ee7645",
      "name" : "family name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${familyName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "lastName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "family_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "be6fa79f-ade5-44c9-afa0-93b8170c47b9",
      "name" : "username",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${username}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "username",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "preferred_username",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "b5d07f15-6a26-4350-9bf9-54d5359c0706",
      "name" : "given name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${givenName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "firstName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "given_name",
        "jsonType.label" : "String"
      }
    } ],
    "useTemplateConfig" : false,
    "useTemplateScope" : false,
    "useTemplateMappers" : false
  }, {
    "id" : "8878b917-5b73-4950-b014-8100b0c405ed",
    "clientId" : "security-admin-console",
    "name" : "${client_security-admin-console}",
    "baseUrl" : "/auth/admin/demo/console/index.html",
    "surrogateAuthRequired" : false,
    "enabled" : true,
    "clientAuthenticatorType" : "client-secret",
    "secret" : "351b34ac-3a0f-4f09-af5a-6b9278c09b85",
    "redirectUris" : [ "/auth/admin/demo/console/*" ],
    "webOrigins" : [ ],
    "notBefore" : 0,
    "bearerOnly" : false,
    "consentRequired" : false,
    "standardFlowEnabled" : true,
    "implicitFlowEnabled" : false,
    "directAccessGrantsEnabled" : false,
    "serviceAccountsEnabled" : false,
    "publicClient" : true,
    "frontchannelLogout" : false,
    "protocol" : "openid-connect",
    "attributes" : { },
    "fullScopeAllowed" : false,
    "nodeReRegistrationTimeout" : 0,
    "protocolMappers" : [ {
      "id" : "9a97567c-d9d6-4f5c-8d0f-ed1e060e598a",
      "name" : "role list",
      "protocol" : "saml",
      "protocolMapper" : "saml-role-list-mapper",
      "consentRequired" : false,
      "config" : {
        "single" : "false",
        "attribute.nameformat" : "Basic",
        "attribute.name" : "Role"
      }
    }, {
      "id" : "6dae9b5b-0948-4591-a69f-51a1590e892f",
      "name" : "username",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${username}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "username",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "preferred_username",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "085240de-a1c4-4735-af6a-2c565e9612cf",
      "name" : "email",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${email}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "email",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "email",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "594a456d-2cdb-49a3-8c40-05145a406f92",
      "name" : "family name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${familyName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "lastName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "family_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "00f77d41-e3d3-443d-9e0f-098379d88ca7",
      "name" : "given name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-property-mapper",
      "consentRequired" : true,
      "consentText" : "${givenName}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "firstName",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "given_name",
        "jsonType.label" : "String"
      }
    }, {
      "id" : "b12cbc25-fe43-4597-84e5-77b506712186",
      "name" : "full name",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-full-name-mapper",
      "consentRequired" : true,
      "consentText" : "${fullName}",
      "config" : {
        "id.token.claim" : "true",
        "access.token.claim" : "true"
      }
    }, {
      "id" : "08f6ee38-4048-407a-8baa-a2e770ae5123",
      "name" : "locale",
      "protocol" : "openid-connect",
      "protocolMapper" : "oidc-usermodel-attribute-mapper",
      "consentRequired" : false,
      "consentText" : "${locale}",
      "config" : {
        "userinfo.token.claim" : "true",
        "user.attribute" : "locale",
        "id.token.claim" : "true",
        "access.token.claim" : "true",
        "claim.name" : "locale",
        "jsonType.label" : "String"
      }
    } ],
    "useTemplateConfig" : false,
    "useTemplateScope" : false,
    "useTemplateMappers" : false
  } ],
  "clientTemplates" : [ ],
  "browserSecurityHeaders" : {
    "xContentTypeOptions" : "nosniff",
    "xRobotsTag" : "none",
    "xFrameOptions" : "SAMEORIGIN",
    "xXSSProtection" : "1; mode=block",
    "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
    "strictTransportSecurity" : "max-age=31536000; includeSubDomains"
  },
  "smtpServer" : { },
  "eventsEnabled" : false,
  "eventsListeners" : [ "jboss-logging" ],
  "enabledEventTypes" : [ ],
  "adminEventsEnabled" : false,
  "adminEventsDetailsEnabled" : false,
  "components" : {
    "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
      "id" : "6908d5c3-07a7-4c00-91d7-462affb7425a",
      "name" : "Consent Required",
      "providerId" : "consent-required",
      "subType" : "anonymous",
      "subComponents" : { },
      "config" : { }
    }, {
      "id" : "f2fbbda7-bc89-474c-80cd-c7817d27e852",
      "name" : "Allowed Client Templates",
      "providerId" : "allowed-client-templates",
      "subType" : "anonymous",
      "subComponents" : { },
      "config" : { }
    }, {
      "id" : "e98e7d78-69d1-4f78-86a9-6aac95c7ce28",
      "name" : "Trusted Hosts",
      "providerId" : "trusted-hosts",
      "subType" : "anonymous",
      "subComponents" : { },
      "config" : {
        "host-sending-registration-request-must-match" : [ "true" ],
        "client-uris-must-match" : [ "true" ]
      }
    }, {
      "id" : "9643017a-e4a3-435e-9c92-a14298a5f7ed",
      "name" : "Allowed Protocol Mapper Types",
      "providerId" : "allowed-protocol-mappers",
      "subType" : "anonymous",
      "subComponents" : { },
      "config" : {
        "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "saml-user-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-address-mapper" ],
        "consent-required-for-all-mappers" : [ "true" ]
      }
    }, {
      "id" : "a72ad67b-392d-462b-a24d-359584948a39",
      "name" : "Max Clients Limit",
      "providerId" : "max-clients",
      "subType" : "anonymous",
      "subComponents" : { },
      "config" : {
        "max-clients" : [ "200" ]
      }
    }, {
      "id" : "39d518a7-6678-415f-aee0-497ddf0bbb8f",
      "name" : "Allowed Protocol Mapper Types",
      "providerId" : "allowed-protocol-mappers",
      "subType" : "authenticated",
      "subComponents" : { },
      "config" : {
        "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "saml-role-list-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper" ],
        "consent-required-for-all-mappers" : [ "true" ]
      }
    }, {
      "id" : "f690379c-6479-4533-ac55-660d4d519849",
      "name" : "Full Scope Disabled",
      "providerId" : "scope",
      "subType" : "anonymous",
      "subComponents" : { },
      "config" : { }
    }, {
      "id" : "fda00934-5922-4028-9e7c-c123100c248f",
      "name" : "Allowed Client Templates",
      "providerId" : "allowed-client-templates",
      "subType" : "authenticated",
      "subComponents" : { },
      "config" : { }
    } ],
    "org.keycloak.keys.KeyProvider" : [ {
      "id" : "1cf453a3-7702-4d4d-8614-72c1fc6b17b6",
      "name" : "hmac-generated",
      "providerId" : "hmac-generated",
      "subComponents" : { },
      "config" : {
        "kid" : [ "012044b2-dfa4-49cb-a4c5-916c19f9b96e" ],
        "secret" : [ "nEC6RCMTKBsF49bfzb3Vv21Vh4TLEaFiRAfvQp2YOOE" ],
        "priority" : [ "100" ]
      }
    }, {
      "id" : "83881f72-2def-46a5-b8ba-99ad0b1e4c95",
      "name" : "rsa-generated",
      "providerId" : "rsa-generated",
      "subComponents" : { },
      "config" : {
        "privateKey" : [ "MIIEowIBAAKCAQEAjc06HxUS54Afmxiw0GXEcD8LS05UVU5KF0hc77CPuT6Sj9atTc1ccRinc24QuE2YdTtYGpELsYGkyul+5r6849vbCsQdcrq1JpLhre/renbjUWz9wBqlphIwPcAR7sSJKHnh+g5K+iOQ7AQaiJGo+tlZrXKfERnahTNVWaZHCIM+82oUvyFaXhV0XyhxQy9RtDq47GnWEgZ9xCvCWPDZJjG6Gm/6rIfZpdqqN5h8GqsOoCUxnLJS0XZP/8Gt/oZF/Y8yMKrOigs83hm1ireMFZDsGgp+z/8+m92CpbASSbO5HXbphO9LZQTZ0BFHHH7DBjF9QZeifQbUH1tyGMzDLQIDAQABAoIBAAavkHf6tGN55QOZDG0m/zYTouKwFMXY5SFn5gnfF0eyrZJemtk6P4uNkAefPuaRsgiE/chy4kxCQpTWoYcboyhTK2a8jG7mYrgo4L8kusORa3JhYy11lC3aWa/vqGjLl3PzGzaBCgP1PVYDc4TQ6Vi6esH0z48s2uLA4ttRPbQm+gJWMTmJpLNydDUBzuQT6OERald4/Ssp0qgZm0Y5WUu0mMiRT8LhNMzJNbZt3S/a22lKA1G/HpyaFD9Fb5hq09TyJqHefzbrWCg6sch8+tKvH6mxqHV2TmrLUtMHzW7tC0tkMh2MShzqqEIYNVFuqzAMEzNczrAYk2L1J2u0JjkCgYEAzWzZW3w9IGAq2yfCiHic3WpgWyadZGHJXRq/x7bkXxowtaHi2A4yc4x0obGbSvqPvFRlYt2v9f5XLmDGLVvS34BeHbZIEK1GUV+5lpzejJ1GkYdSnhPquLbmRkDrYG1a/dU4DLSKvKc45jmhwRdheeTvFW3z1XZqshrTIxBwwLsCgYEAsLZvShoO9M5uhWCnsvMZ6gRm7Nw5FmCfZm0WM1Cj9mWngFCcWhxZEheTOhiqNcnGi8e8xlDJAI4iimUD4ZRqeTs/CIvbHNq8DICf6aSMAaba+jxycEzVu/xZsNkzV1SaKcPll+fjV8vRKA0JAaioQMkrmhRCsu/ODNjo4MYd4TcCgYB3b8oQfvOrVz6TnVJltnq94ZOUa6cnLhO9pkfK/nNZOAkKEc2qgNakiA1n1bPMrFHV1dv815fvFqnptSqERNceS6xs6gaMa7JurZFiGGLsrqTRCDTo4/uc2fqY7jXsIqi83LNx76aaeT+D3A5IDigGjyzS8NLMUcVHOIF56Z0k8QKBgAstLrLAHSwMll7nMxQVXhE4AA6BCzdIGyzOP3Y1ZnliCosKDimA231ScmRdRP6r6VvT4TOlzmCznKmmI+2zhlxui9kNh2k2yGf+Bp8vYg+ErxrekdpacbY3CrEtu5qNZka39iB6cR2PbYYb9PLe6O1YC+Lt3x4UHrMfUPNOdHtXAoGBAKpncRXGyL05nnzFvK68BfoxSpd4aJk0Wkr9nOxZGFJj8v/LeUuxN6LOGqw4z8Sfdx3AI/6+JJAWk9sUlQ4ejAMFwR67UXI1eLkvs5x+U9g6DaZUMpgTUQhkfinZ3b822L6B20O+5Xz6aOGDbcWR+X/MAyj/gfnYR/TvXCq5v+sE" ],
        "certificate" : [ "MIIClzCCAX8CBgFi1H8iNDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARkZW1vMB4XDTE4MDQxNzE2NDM0NFoXDTI4MDQxNzE2NDUyNFowDzENMAsGA1UEAwwEZGVtbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI3NOh8VEueAH5sYsNBlxHA/C0tOVFVOShdIXO+wj7k+ko/WrU3NXHEYp3NuELhNmHU7WBqRC7GBpMrpfua+vOPb2wrEHXK6tSaS4a3v63p241Fs/cAapaYSMD3AEe7EiSh54foOSvojkOwEGoiRqPrZWa1ynxEZ2oUzVVmmRwiDPvNqFL8hWl4VdF8ocUMvUbQ6uOxp1hIGfcQrwljw2SYxuhpv+qyH2aXaqjeYfBqrDqAlMZyyUtF2T//Brf6GRf2PMjCqzooLPN4ZtYq3jBWQ7BoKfs//PpvdgqWwEkmzuR126YTvS2UE2dARRxx+wwYxfUGXon0G1B9bchjMwy0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAavonr2grkWPCSLDRRCyTly2q/By5FYhkN5Bu7c2pxQy/k1OKJUBz+GIPxSL6MrPmHoWHM9fpD9nLCa1VHbHkEiu9p0c+2CDPVAyYvVbADVdgL+xp19TMyvETMfS1tJKVyJbqL8RsxzjWm1qI19VmVWNNHUGXpuPp35DL5tL/RkooY6+oNamsiNwR6xXmfqY7l6w8HA4y8It3yaeHy6N2ffjI/2AtXTyISuEEv1Lybr5op4jKRYLqv+ly7aBeNIGGnHFXlGyCqv8dSWSYXA1S83x4LeTHrj7rAC4fORY2Q5VNmhUAYYE5Vy+zxAHSoQn+cEf2qJsr9xRlYy8nzyXukw==" ],
        "priority" : [ "100" ]
      }
    }, {
      "id" : "46800710-eced-4804-a79e-32f7c5797b04",
      "name" : "aes-generated",
      "providerId" : "aes-generated",
      "subComponents" : { },
      "config" : {
        "kid" : [ "2b922283-df55-4424-8bef-3f2ff5ba0bfa" ],
        "secret" : [ "Ry49w356XdzGeEQbsupsvA" ],
        "priority" : [ "100" ]
      }
    } ]
  },
  "internationalizationEnabled" : false,
  "supportedLocales" : [ ],
  "authenticationFlows" : [ {
    "id" : "a48d9b79-b52f-4d29-b831-ecb9098352ad",
    "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",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "idp-email-verification",
      "requirement" : "ALTERNATIVE",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "requirement" : "ALTERNATIVE",
      "priority" : 30,
      "flowAlias" : "Verify Existing Account by Re-authentication",
      "userSetupAllowed" : false,
      "autheticatorFlow" : true
    } ]
  }, {
    "id" : "03731267-4cd9-478d-ac04-403d1d832d46",
    "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",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "auth-otp-form",
      "requirement" : "OPTIONAL",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  }, {
    "id" : "bb3fec2b-49dc-4ca3-bb31-8acb74b3e1bd",
    "alias" : "browser",
    "description" : "browser based authentication",
    "providerId" : "basic-flow",
    "topLevel" : true,
    "builtIn" : true,
    "authenticationExecutions" : [ {
      "authenticator" : "auth-cookie",
      "requirement" : "ALTERNATIVE",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "auth-spnego",
      "requirement" : "DISABLED",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "identity-provider-redirector",
      "requirement" : "ALTERNATIVE",
      "priority" : 25,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "requirement" : "ALTERNATIVE",
      "priority" : 30,
      "flowAlias" : "forms",
      "userSetupAllowed" : false,
      "autheticatorFlow" : true
    } ]
  }, {
    "id" : "84567fef-a17f-424c-9f30-c5ae041beeee",
    "alias" : "clients",
    "description" : "Base authentication for clients",
    "providerId" : "client-flow",
    "topLevel" : true,
    "builtIn" : true,
    "authenticationExecutions" : [ {
      "authenticator" : "client-secret",
      "requirement" : "ALTERNATIVE",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "client-jwt",
      "requirement" : "ALTERNATIVE",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  }, {
    "id" : "731a2721-79ff-46ec-8dcb-ea7d19f86d33",
    "alias" : "direct grant",
    "description" : "OpenID Connect Resource Owner Grant",
    "providerId" : "basic-flow",
    "topLevel" : true,
    "builtIn" : true,
    "authenticationExecutions" : [ {
      "authenticator" : "direct-grant-validate-username",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "direct-grant-validate-password",
      "requirement" : "REQUIRED",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "direct-grant-validate-otp",
      "requirement" : "OPTIONAL",
      "priority" : 30,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  }, {
    "id" : "3c5c6d83-ccb5-420d-8370-253c43a6d598",
    "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",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  }, {
    "id" : "81f1a3b5-7737-4351-a4bd-25e98b536798",
    "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",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticatorConfig" : "create unique user config",
      "authenticator" : "idp-create-user-if-unique",
      "requirement" : "ALTERNATIVE",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "requirement" : "ALTERNATIVE",
      "priority" : 30,
      "flowAlias" : "Handle Existing Account",
      "userSetupAllowed" : false,
      "autheticatorFlow" : true
    } ]
  }, {
    "id" : "46ba7967-ea06-45e3-98af-11200a34473e",
    "alias" : "forms",
    "description" : "Username, password, otp and other auth forms.",
    "providerId" : "basic-flow",
    "topLevel" : false,
    "builtIn" : true,
    "authenticationExecutions" : [ {
      "authenticator" : "auth-username-password-form",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "auth-otp-form",
      "requirement" : "OPTIONAL",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  }, {
    "id" : "4f2620ae-bb89-4d85-b81e-6e5d20c78a47",
    "alias" : "registration",
    "description" : "registration flow",
    "providerId" : "basic-flow",
    "topLevel" : true,
    "builtIn" : true,
    "authenticationExecutions" : [ {
      "authenticator" : "registration-page-form",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "flowAlias" : "registration form",
      "userSetupAllowed" : false,
      "autheticatorFlow" : true
    } ]
  }, {
    "id" : "7fb032fb-dac9-4ea8-9d63-678753437440",
    "alias" : "registration form",
    "description" : "registration form",
    "providerId" : "form-flow",
    "topLevel" : false,
    "builtIn" : true,
    "authenticationExecutions" : [ {
      "authenticator" : "registration-user-creation",
      "requirement" : "REQUIRED",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "registration-profile-action",
      "requirement" : "REQUIRED",
      "priority" : 40,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "registration-password-action",
      "requirement" : "REQUIRED",
      "priority" : 50,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "registration-recaptcha-action",
      "requirement" : "DISABLED",
      "priority" : 60,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  }, {
    "id" : "75600e80-cae6-4347-a506-ddf6477cd7e9",
    "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",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "reset-credential-email",
      "requirement" : "REQUIRED",
      "priority" : 20,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "reset-password",
      "requirement" : "REQUIRED",
      "priority" : 30,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    }, {
      "authenticator" : "reset-otp",
      "requirement" : "OPTIONAL",
      "priority" : 40,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  }, {
    "id" : "4990dbc0-bb0b-48b5-8f72-945adcf77d39",
    "alias" : "saml ecp",
    "description" : "SAML ECP Profile Authentication Flow",
    "providerId" : "basic-flow",
    "topLevel" : true,
    "builtIn" : true,
    "authenticationExecutions" : [ {
      "authenticator" : "http-basic-authenticator",
      "requirement" : "REQUIRED",
      "priority" : 10,
      "userSetupAllowed" : false,
      "autheticatorFlow" : false
    } ]
  } ],
  "authenticatorConfig" : [ {
    "id" : "da120730-f96f-4a0b-9f97-48d63823b067",
    "alias" : "create unique user config",
    "config" : {
      "require.password.update.after.registration" : "false"
    }
  }, {
    "id" : "0c76ade9-f703-4606-bae9-28f0bf131e11",
    "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,
    "config" : { }
  }, {
    "alias" : "UPDATE_PASSWORD",
    "name" : "Update Password",
    "providerId" : "UPDATE_PASSWORD",
    "enabled" : true,
    "defaultAction" : false,
    "config" : { }
  }, {
    "alias" : "UPDATE_PROFILE",
    "name" : "Update Profile",
    "providerId" : "UPDATE_PROFILE",
    "enabled" : true,
    "defaultAction" : false,
    "config" : { }
  }, {
    "alias" : "VERIFY_EMAIL",
    "name" : "Verify Email",
    "providerId" : "VERIFY_EMAIL",
    "enabled" : true,
    "defaultAction" : false,
    "config" : { }
  }, {
    "alias" : "terms_and_conditions",
    "name" : "Terms and Conditions",
    "providerId" : "terms_and_conditions",
    "enabled" : false,
    "defaultAction" : false,
    "config" : { }
  } ],
  "browserFlow" : "browser",
  "registrationFlow" : "registration",
  "directGrantFlow" : "direct grant",
  "resetCredentialsFlow" : "reset credentials",
  "clientAuthenticationFlow" : "clients",
  "dockerAuthenticationFlow" : "docker auth",
  "attributes" : {
    "_browser_header.xXSSProtection" : "1; mode=block",
    "_browser_header.xFrameOptions" : "SAMEORIGIN",
    "_browser_header.strictTransportSecurity" : "max-age=31536000; includeSubDomains",
    "permanentLockout" : "false",
    "quickLoginCheckMilliSeconds" : "1000",
    "_browser_header.xRobotsTag" : "none",
    "maxFailureWaitSeconds" : "900",
    "minimumQuickLoginWaitSeconds" : "60",
    "failureFactor" : "30",
    "actionTokenGeneratedByUserLifespan" : "300",
    "maxDeltaTimeSeconds" : "43200",
    "_browser_header.xContentTypeOptions" : "nosniff",
    "actionTokenGeneratedByAdminLifespan" : "43200",
    "bruteForceProtected" : "false",
    "_browser_header.contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
    "waitIncrementSeconds" : "60"
  },
  "keycloakVersion" : "3.4.3.Final"
}

================================================
FILE: mvnw
================================================
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------

# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
#   JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
#   M2_HOME - location of maven2's installed home dir
#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
#     e.g. to debug Maven itself, use
#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------

if [ -z "$MAVEN_SKIP_RC" ] ; then

  if [ -f /etc/mavenrc ] ; then
    . /etc/mavenrc
  fi

  if [ -f "$HOME/.mavenrc" ] ; then
    . "$HOME/.mavenrc"
  fi

fi

# OS specific support.  $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
  CYGWIN*) cygwin=true ;;
  MINGW*) mingw=true;;
  Darwin*) darwin=true
    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
    if [ -z "$JAVA_HOME" ]; then
      if [ -x "/usr/libexec/java_home" ]; then
        export JAVA_HOME="`/usr/libexec/java_home`"
      else
        export JAVA_HOME="/Library/Java/Home"
      fi
    fi
    ;;
esac

if [ -z "$JAVA_HOME" ] ; then
  if [ -r /etc/gentoo-release ] ; then
    JAVA_HOME=`java-config --jre-home`
  fi
fi

if [ -z "$M2_HOME" ] ; then
  ## resolve links - $0 may be a link to maven's home
  PRG="$0"

  # need this for relative symlinks
  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
      PRG="$link"
    else
      PRG="`dirname "$PRG"`/$link"
    fi
  done

  saveddir=`pwd`

  M2_HOME=`dirname "$PRG"`/..

  # make it fully qualified
  M2_HOME=`cd "$M2_HOME" && pwd`

  cd "$saveddir"
  # echo Using m2 at $M2_HOME
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --unix "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
  [ -n "$M2_HOME" ] &&
    M2_HOME="`(cd "$M2_HOME"; pwd)`"
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
  # TODO classpath?
fi

if [ -z "$JAVA_HOME" ]; then
  javaExecutable="`which javac`"
  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
    # readlink(1) is not available as standard on Solaris 10.
    readLink=`which readlink`
    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
      if $darwin ; then
        javaHome="`dirname \"$javaExecutable\"`"
        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
      else
        javaExecutable="`readlink -f \"$javaExecutable\"`"
      fi
      javaHome="`dirname \"$javaExecutable\"`"
      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
      JAVA_HOME="$javaHome"
      export JAVA_HOME
    fi
  fi
fi

if [ -z "$JAVACMD" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  else
    JAVACMD="`which java`"
  fi
fi

if [ ! -x "$JAVACMD" ] ; then
  echo "Error: JAVA_HOME is not defined correctly." >&2
  echo "  We cannot execute $JAVACMD" >&2
  exit 1
fi

if [ -z "$JAVA_HOME" ] ; then
  echo "Warning: JAVA_HOME environment variable is not set."
fi

CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher

# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {

  if [ -z "$1" ]
  then
    echo "Path not specified to find_maven_basedir"
    return 1
  fi

  basedir="$1"
  wdir="$1"
  while [ "$wdir" != '/' ] ; do
    if [ -d "$wdir"/.mvn ] ; then
      basedir=$wdir
      break
    fi
    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
    if [ -d "${wdir}" ]; then
      wdir=`cd "$wdir/.."; pwd`
    fi
    # end of workaround
  done
  echo "${basedir}"
}

# concatenates all lines of a file
concat_lines() {
  if [ -f "$1" ]; then
    echo "$(tr -s '\n' ' ' < "$1")"
  fi
}

BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
  exit 1;
fi

export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
echo $MAVEN_PROJECTBASEDIR
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --path --windows "$M2_HOME"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi

WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

exec "$JAVACMD" \
  $MAVEN_OPTS \
  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"


================================================
FILE: mvnw.cmd
================================================
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements.  See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership.  The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License.  You may obtain a copy of the License at
@REM
@REM    http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied.  See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------

@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM     e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------

@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%

@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")

@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre

@setlocal

set ERROR_CODE=0

@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal

@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome

echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init

echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error

@REM ==== END VALIDATION ====

:init

@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.

set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir

set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir

:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir

:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"

:endDetectBaseDir

IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig

@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%

:endReadAdditionalConfig

SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"

set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain

%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end

:error
set ERROR_CODE=1

:end
@endlocal & set ERROR_CODE=%ERROR_CODE%

if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost

@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause

if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%

exit /B %ERROR_CODE%


================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>de.tdlabs.training</groupId>
	<artifactId>spring-boot-2-oauth-example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-boot-2-oauth-example</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<spring-cloud.version>Finchley.M9</spring-cloud.version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity4</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-oauth2-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-oauth2-jose</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
			<scope>runtime</scope>
		</dependency>

	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</pluginRepository>
		<pluginRepository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>


</project>


================================================
FILE: readme.md
================================================
# PoC for Spring Boot 2 + Spring Security 5 + Keycloak 3.4.3
 
This example project uses the OpenID Connect support in Spring Security 5 without using the Keycloak adapter  
and is inspired by [this](http://info.michael-simons.eu/2017/12/28/use-keycloak-with-your-spring-boot-2-application/) blog post by Michael Simons.
 
 Features:
 - SSO / SLO
 - Support for extracting roles from Keycloak AccessToken
 - Link to Keycloak Account page with back-link to the application

## Setup

Import the `demo` realm into Keycloak via

```
bin/standalone.sh -Dkeycloak.migration.action=import
-Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=/path/to/demo-realm.json
-Dkeycloak.migration.strategy=OVERWRITE_EXISTING
```

Keycloak is assumed to run on port 8080 on localhost.  
The demo realm contains two users `tester` and `admin` both with password `test`.
 
The example runs on port 8082.



================================================
FILE: src/main/java/demo/SpringBoot2App.java
================================================
package demo;

import static org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;

import java.security.Principal;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoderJwkSupport;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.UriComponentsBuilder;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@SpringBootApplication
public class SpringBoot2App {

	public static void main(String[] args) {
		SpringApplication.run(SpringBoot2App.class, args);
	}
}

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
class WebSecurityConfig {

	@Bean
	public WebSecurityConfigurerAdapter webSecurityConfigurer( //
			@Value("${kc.realm}") String realm, //
			KeycloakOauth2UserService keycloakOidcUserService, //
			KeycloakLogoutHandler keycloakLogoutHandler //
	) {
		return new WebSecurityConfigurerAdapter() {
			@Override
			public void configure(HttpSecurity http) throws Exception {

				http
						// Configure session management to your needs.
						// I need this as a basis for a classic, server side rendered application
						.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
						// Depends on your taste. You can configure single paths here
						// or allow everything a I did and then use method based security
						// like in the controller below
						.authorizeRequests().anyRequest().permitAll().and()
						// Propagate logouts via /logout to Keycloak
						.logout().addLogoutHandler(keycloakLogoutHandler).and()
						// This is the point where OAuth2 login of Spring 5 gets enabled
						.oauth2Login().userInfoEndpoint().oidcUserService(keycloakOidcUserService).and()
						// I don't want a page with different clients as login options
						// So i use the constant from OAuth2AuthorizationRequestRedirectFilter
						// plus the configured realm as immediate redirect to Keycloak
						.loginPage(DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/" + realm);
			}
		};
	}

	@Bean
	KeycloakOauth2UserService keycloakOidcUserService(OAuth2ClientProperties oauth2ClientProperties) {

		// TODO use default JwtDecoder - where to grab?
		NimbusJwtDecoderJwkSupport jwtDecoder = new NimbusJwtDecoderJwkSupport(
				oauth2ClientProperties.getProvider().get("keycloak").getJwkSetUri());

		SimpleAuthorityMapper authoritiesMapper = new SimpleAuthorityMapper();
		authoritiesMapper.setConvertToUpperCase(true);

		return new KeycloakOauth2UserService(jwtDecoder, authoritiesMapper);
	}

	@Bean
	KeycloakLogoutHandler keycloakLogoutHandler() {
		return new KeycloakLogoutHandler(new RestTemplate());
	}
}

@RequiredArgsConstructor
class KeycloakOauth2UserService extends OidcUserService {

	private final OAuth2Error INVALID_REQUEST = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);

	private final JwtDecoder jwtDecoder;

	private final GrantedAuthoritiesMapper authoritiesMapper;

	/**
	 * Augments {@link OidcUserService#loadUser(OidcUserRequest)} to add authorities
	 * provided by Keycloak.
	 * 
	 * Needed because {@link OidcUserService#loadUser(OidcUserRequest)} (currently)
	 * does not provide a hook for adding custom authorities from a
	 * {@link OidcUserRequest}.
	 */
	@Override
	public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {

		OidcUser user = super.loadUser(userRequest);

		Set<GrantedAuthority> authorities = new LinkedHashSet<>();
		authorities.addAll(user.getAuthorities());
		authorities.addAll(extractKeycloakAuthorities(userRequest));

		return new DefaultOidcUser(authorities, userRequest.getIdToken(), user.getUserInfo(), "preferred_username");
	}

	/**
	 * Extracts {@link GrantedAuthority GrantedAuthorities} from the AccessToken in
	 * the {@link OidcUserRequest}.
	 * 
	 * @param userRequest
	 * @return
	 */
	private Collection<? extends GrantedAuthority> extractKeycloakAuthorities(OidcUserRequest userRequest) {

		Jwt token = parseJwt(userRequest.getAccessToken().getTokenValue());

		// Would be great if Spring Security would provide something like a plugable
		// OidcUserRequestAuthoritiesExtractor interface to hide the junk below...

		@SuppressWarnings("unchecked")
		Map<String, Object> resourceMap = (Map<String, Object>) token.getClaims().get("resource_access");
		String clientId = userRequest.getClientRegistration().getClientId();

		@SuppressWarnings("unchecked")
		Map<String, Map<String, Object>> clientResource = (Map<String, Map<String, Object>>) resourceMap.get(clientId);
		if (CollectionUtils.isEmpty(clientResource)) {
			return Collections.emptyList();
		}

		@SuppressWarnings("unchecked")
		List<String> clientRoles = (List<String>) clientResource.get("roles");
		if (CollectionUtils.isEmpty(clientRoles)) {
			return Collections.emptyList();
		}

		Collection<? extends GrantedAuthority> authorities = AuthorityUtils
				.createAuthorityList(clientRoles.toArray(new String[0]));
		if (authoritiesMapper == null) {
			return authorities;
		}

		return authoritiesMapper.mapAuthorities(authorities);
	}

	private Jwt parseJwt(String accessTokenValue) {
		try {
			// Token is already verified by spring security infrastructure
			return jwtDecoder.decode(accessTokenValue);
		} catch (JwtException e) {
			throw new OAuth2AuthenticationException(INVALID_REQUEST, e);
		}
	}
}

/**
 * Propagates logouts to Keycloak.
 * 
 * Necessary because Spring Security 5 (currently) doesn't support
 * end-session-endpoints.
 */
@Slf4j
@RequiredArgsConstructor
class KeycloakLogoutHandler extends SecurityContextLogoutHandler {

	private final RestTemplate restTemplate;

	@Override
	public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
		super.logout(request, response, authentication);

		propagateLogoutToKeycloak((OidcUser) authentication.getPrincipal());
	}

	private void propagateLogoutToKeycloak(OidcUser user) {

		String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";

		UriComponentsBuilder builder = UriComponentsBuilder //
				.fromUriString(endSessionEndpoint) //
				.queryParam("id_token_hint", user.getIdToken().getTokenValue());

		ResponseEntity<String> logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
		if (logoutResponse.getStatusCode().is2xxSuccessful()) {
			log.info("Successfulley logged out in Keycloak");
		} else {
			log.info("Could not propagate logout to Keycloak");
		}
	}
}

@Controller
class DemoController {

	@PreAuthorize("hasRole('ROLE_USER')")
	@GetMapping("/protected")
	public ModelAndView protectedPage(Principal principal) {
		return new ModelAndView("app", Collections.singletonMap("principal", principal));
	}

	@PreAuthorize("hasRole('ROLE_ADMIN')")
	@GetMapping("/admin")
	public ModelAndView adminPage(Principal principal) {
		return new ModelAndView("admin", Collections.singletonMap("principal", principal));
	}

	@GetMapping("/")
	public String unprotectedPage(Model model, Principal principal) {
		model.addAttribute("principal", principal);
		return "index";
	}

	@GetMapping("/account")
	public String redirectToAccountPage(@AuthenticationPrincipal OAuth2AuthenticationToken authToken) {

		if (authToken == null) {
			return "redirect:/";
		}

		OidcUser user = (OidcUser) authToken.getPrincipal();

		// Provides a back-link to the application
		return "redirect:" + user.getIssuer() + "/account?referrer=" + user.getIdToken().getAuthorizedParty();
	}
}

================================================
FILE: src/main/resources/application.yml
================================================
server:
  port: 8082

kc:
  base-url: http://localhost:8080/auth
  realm: demo
  realm-url: ${kc.base-url}/realms/${kc.realm}

spring:
  security:
    oauth2:
      client:
        registration:
          demo:
            client-id: app-demo
            client-name: Demo App
            client-secret: e3f519b4-0272-4261-9912-8b7453ac4ecd
            provider: keycloak
            authorization-grant-type: authorization_code
            scope: openid, profile
            redirect-uri-template: "{baseUrl}/login/oauth2/code/{registrationId}"
        provider:
          keycloak:
            authorization-uri: ${kc.realm-url}/protocol/openid-connect/auth
            jwk-set-uri: ${kc.realm-url}/protocol/openid-connect/certs
            token-uri: ${kc.realm-url}/protocol/openid-connect/token
# would be cool if there was a end-session-uri to propagate logouts 

#  User info endpoint not needed since Keycloak uses self-contained value tokens
#            user-info-uri: ${kc.realm-url}/protocol/openid-connect/userinfo
            user-name-attribute: preferred_username

================================================
FILE: src/main/resources/templates/admin.html
================================================
<!DOCTYPE html>
<html>
<head>
<title>Admin Area</title>
</head>
<body>
   <h1>My cool App (Admin)</h1>
   <div th:if="${principal}">
      <p th:text="${principal.getName()}">Current User</p>
   </div>
   <a href="/">Home</a>
</body>
</html>

================================================
FILE: src/main/resources/templates/app.html
================================================
<!DOCTYPE html>
<html>
<head>
<title>App</title>
</head>
<body>
	<h1>My cool App</h1>
	<div th:if="${principal}">
		<p th:text="${principal.getName()}">Current User</p>
	</div>
	<a href="/">Home</a>
</body>
</html>

================================================
FILE: src/main/resources/templates/index.html
================================================
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<title>Demo App</title>
</head>
<body>
	<ul>
		<li><a href="#" th:href="@{/protected}">App</a></li>
		<li sec:authorize="hasRole('ROLE_ADMIN')"><a href="#"
			th:href="@{/admin}">Admin</a></li>
		<li th:if="${principal}"><a href="#" th:href="@{/account}">Account</a></li>
	</ul>

	<form action="logout" method="post" th:if="${principal}">
		<input type="hidden" th:name="${_csrf.parameterName}"
			th:value="${_csrf.token}" />

		<button>Logout</button>
	</form>
</body>
</html>
Download .txt
gitextract_swett08m/

├── .gitignore
├── .mvn/
│   └── wrapper/
│       ├── maven-wrapper.jar
│       └── maven-wrapper.properties
├── demo-realm.json
├── mvnw
├── mvnw.cmd
├── pom.xml
├── readme.md
└── src/
    └── main/
        ├── java/
        │   └── demo/
        │       └── SpringBoot2App.java
        └── resources/
            ├── application.yml
            └── templates/
                ├── admin.html
                ├── app.html
                └── index.html
Download .txt
SYMBOL INDEX (18 symbols across 1 files)

FILE: src/main/java/demo/SpringBoot2App.java
  class SpringBoot2App (line 58) | @SpringBootApplication
    method main (line 61) | public static void main(String[] args) {
  class WebSecurityConfig (line 66) | @Configuration
    method webSecurityConfigurer (line 70) | @Bean
    method keycloakOidcUserService (line 100) | @Bean
    method keycloakLogoutHandler (line 113) | @Bean
  class KeycloakOauth2UserService (line 119) | @RequiredArgsConstructor
    method loadUser (line 136) | @Override
    method extractKeycloakAuthorities (line 155) | private Collection<? extends GrantedAuthority> extractKeycloakAuthorit...
    method parseJwt (line 187) | private Jwt parseJwt(String accessTokenValue) {
  class KeycloakLogoutHandler (line 203) | @Slf4j
    method logout (line 209) | @Override
    method propagateLogoutToKeycloak (line 216) | private void propagateLogoutToKeycloak(OidcUser user) {
  class DemoController (line 233) | @Controller
    method protectedPage (line 236) | @PreAuthorize("hasRole('ROLE_USER')")
    method adminPage (line 242) | @PreAuthorize("hasRole('ROLE_ADMIN')")
    method unprotectedPage (line 248) | @GetMapping("/")
    method redirectToAccountPage (line 254) | @GetMapping("/account")
Condensed preview — 13 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (91K chars).
[
  {
    "path": ".gitignore",
    "chars": 249,
    "preview": "target/\n!.mvn/wrapper/maven-wrapper.jar\n\n### STS ###\n.apt_generated\n.classpath\n.factorypath\n.project\n.settings\n.springBe"
  },
  {
    "path": ".mvn/wrapper/maven-wrapper.properties",
    "chars": 110,
    "preview": "distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip\n"
  },
  {
    "path": "demo-realm.json",
    "chars": 53780,
    "preview": "{\n  \"id\" : \"demo\",\n  \"realm\" : \"demo\",\n  \"notBefore\" : 0,\n  \"revokeRefreshToken\" : false,\n  \"refreshTokenMaxReuse\" : 0,\n"
  },
  {
    "path": "mvnw",
    "chars": 6468,
    "preview": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Softwa"
  },
  {
    "path": "mvnw.cmd",
    "chars": 4994,
    "preview": "@REM ----------------------------------------------------------------------------\n@REM Licensed to the Apache Software F"
  },
  {
    "path": "pom.xml",
    "chars": 3602,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n\txmlns:xsi=\"http://www.w3.org/"
  },
  {
    "path": "readme.md",
    "chars": 901,
    "preview": "# PoC for Spring Boot 2 + Spring Security 5 + Keycloak 3.4.3\n \nThis example project uses the OpenID Connect support in S"
  },
  {
    "path": "src/main/java/demo/SpringBoot2App.java",
    "chars": 10173,
    "preview": "package demo;\n\nimport static org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.DEF"
  },
  {
    "path": "src/main/resources/application.yml",
    "chars": 1079,
    "preview": "server:\n  port: 8082\n\nkc:\n  base-url: http://localhost:8080/auth\n  realm: demo\n  realm-url: ${kc.base-url}/realms/${kc.r"
  },
  {
    "path": "src/main/resources/templates/admin.html",
    "chars": 241,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<title>Admin Area</title>\n</head>\n<body>\n   <h1>My cool App (Admin)</h1>\n   <div th:if=\"${"
  },
  {
    "path": "src/main/resources/templates/app.html",
    "chars": 214,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<title>App</title>\n</head>\n<body>\n\t<h1>My cool App</h1>\n\t<div th:if=\"${principal}\">\n\t\t<p t"
  },
  {
    "path": "src/main/resources/templates/index.html",
    "chars": 643,
    "preview": "<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\"\n\txmlns:th=\"http://www.thymeleaf.org\"\n\txmlns:sec=\"http://www.t"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the thomasdarimont/spring-boot-2-keycloak-oauth-example GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 13 files (80.5 KB), approximately 26.0k tokens, and a symbol index with 18 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!