├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── src
└── main
│ ├── resources
│ ├── templates
│ │ ├── app.html
│ │ ├── admin.html
│ │ └── index.html
│ └── application.yml
│ └── java
│ └── demo
│ └── SpringBoot2App.java
├── .gitignore
├── readme.md
├── pom.xml
├── mvnw.cmd
├── mvnw
└── demo-realm.json
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/thomasdarimont/spring-boot-2-keycloak-oauth-example/HEAD/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip
2 |
--------------------------------------------------------------------------------
/src/main/resources/templates/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | App
5 |
6 |
7 | My cool App
8 |
11 | Home
12 |
13 |
--------------------------------------------------------------------------------
/src/main/resources/templates/admin.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Admin Area
5 |
6 |
7 | My cool App (Admin)
8 |
11 | Home
12 |
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 |
4 | ### STS ###
5 | .apt_generated
6 | .classpath
7 | .factorypath
8 | .project
9 | .settings
10 | .springBeans
11 |
12 | ### IntelliJ IDEA ###
13 | .idea
14 | *.iws
15 | *.iml
16 | *.ipr
17 |
18 | ### NetBeans ###
19 | nbproject/private/
20 | build/
21 | nbbuild/
22 | dist/
23 | nbdist/
24 | .nb-gradle/
--------------------------------------------------------------------------------
/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Demo App
7 |
8 |
9 |
15 |
16 |
22 |
23 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # PoC for Spring Boot 2 + Spring Security 5 + Keycloak 3.4.3
2 |
3 | This example project uses the OpenID Connect support in Spring Security 5 without using the Keycloak adapter
4 | 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.
5 |
6 | Features:
7 | - SSO / SLO
8 | - Support for extracting roles from Keycloak AccessToken
9 | - Link to Keycloak Account page with back-link to the application
10 |
11 | ## Setup
12 |
13 | Import the `demo` realm into Keycloak via
14 |
15 | ```
16 | bin/standalone.sh -Dkeycloak.migration.action=import
17 | -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=/path/to/demo-realm.json
18 | -Dkeycloak.migration.strategy=OVERWRITE_EXISTING
19 | ```
20 |
21 | Keycloak is assumed to run on port 8080 on localhost.
22 | The demo realm contains two users `tester` and `admin` both with password `test`.
23 |
24 | The example runs on port 8082.
25 |
26 |
--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8082
3 |
4 | kc:
5 | base-url: http://localhost:8080/auth
6 | realm: demo
7 | realm-url: ${kc.base-url}/realms/${kc.realm}
8 |
9 | spring:
10 | security:
11 | oauth2:
12 | client:
13 | registration:
14 | demo:
15 | client-id: app-demo
16 | client-name: Demo App
17 | client-secret: e3f519b4-0272-4261-9912-8b7453ac4ecd
18 | provider: keycloak
19 | authorization-grant-type: authorization_code
20 | scope: openid, profile
21 | redirect-uri-template: "{baseUrl}/login/oauth2/code/{registrationId}"
22 | provider:
23 | keycloak:
24 | authorization-uri: ${kc.realm-url}/protocol/openid-connect/auth
25 | jwk-set-uri: ${kc.realm-url}/protocol/openid-connect/certs
26 | token-uri: ${kc.realm-url}/protocol/openid-connect/token
27 | # would be cool if there was a end-session-uri to propagate logouts
28 |
29 | # User info endpoint not needed since Keycloak uses self-contained value tokens
30 | # user-info-uri: ${kc.realm-url}/protocol/openid-connect/userinfo
31 | user-name-attribute: preferred_username
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | de.tdlabs.training
8 | spring-boot-2-oauth-example
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | spring-boot-2-oauth-example
13 | Demo project for Spring Boot
14 |
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 2.0.1.RELEASE
19 |
20 |
21 |
22 |
23 | UTF-8
24 | UTF-8
25 | 1.8
26 | Finchley.M9
27 |
28 |
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-web
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-thymeleaf
39 |
40 |
41 |
42 | org.thymeleaf.extras
43 | thymeleaf-extras-springsecurity4
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-security
49 |
50 |
51 |
52 | org.springframework.security
53 | spring-security-oauth2-client
54 |
55 |
56 | org.springframework.security
57 | spring-security-oauth2-jose
58 |
59 |
60 |
61 | org.projectlombok
62 | lombok
63 | true
64 |
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-devtools
69 | true
70 | runtime
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | org.springframework.cloud
79 | spring-cloud-dependencies
80 | ${spring-cloud.version}
81 | pom
82 | import
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | org.springframework.boot
91 | spring-boot-maven-plugin
92 |
93 |
94 |
95 |
96 |
97 |
98 | spring-snapshots
99 | Spring Snapshots
100 | https://repo.spring.io/snapshot
101 |
102 | true
103 |
104 |
105 |
106 | spring-milestones
107 | Spring Milestones
108 | https://repo.spring.io/milestone
109 |
110 | false
111 |
112 |
113 |
114 |
115 |
116 |
117 | spring-snapshots
118 | Spring Snapshots
119 | https://repo.spring.io/snapshot
120 |
121 | true
122 |
123 |
124 |
125 | spring-milestones
126 | Spring Milestones
127 | https://repo.spring.io/milestone
128 |
129 | false
130 |
131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/src/main/java/demo/SpringBoot2App.java:
--------------------------------------------------------------------------------
1 | package demo;
2 |
3 | import static org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
4 |
5 | import java.security.Principal;
6 | import java.util.Collection;
7 | import java.util.Collections;
8 | import java.util.LinkedHashSet;
9 | import java.util.List;
10 | import java.util.Map;
11 | import java.util.Set;
12 |
13 | import javax.servlet.http.HttpServletRequest;
14 | import javax.servlet.http.HttpServletResponse;
15 |
16 | import org.springframework.beans.factory.annotation.Value;
17 | import org.springframework.boot.SpringApplication;
18 | import org.springframework.boot.autoconfigure.SpringBootApplication;
19 | import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
20 | import org.springframework.context.annotation.Bean;
21 | import org.springframework.context.annotation.Configuration;
22 | import org.springframework.http.ResponseEntity;
23 | import org.springframework.security.access.prepost.PreAuthorize;
24 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
25 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
26 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
27 | import org.springframework.security.config.http.SessionCreationPolicy;
28 | import org.springframework.security.core.Authentication;
29 | import org.springframework.security.core.GrantedAuthority;
30 | import org.springframework.security.core.annotation.AuthenticationPrincipal;
31 | import org.springframework.security.core.authority.AuthorityUtils;
32 | import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
33 | import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
34 | import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
35 | import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
36 | import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
37 | import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
38 | import org.springframework.security.oauth2.core.OAuth2Error;
39 | import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
40 | import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
41 | import org.springframework.security.oauth2.core.oidc.user.OidcUser;
42 | import org.springframework.security.oauth2.jwt.Jwt;
43 | import org.springframework.security.oauth2.jwt.JwtDecoder;
44 | import org.springframework.security.oauth2.jwt.JwtException;
45 | import org.springframework.security.oauth2.jwt.NimbusJwtDecoderJwkSupport;
46 | import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
47 | import org.springframework.stereotype.Controller;
48 | import org.springframework.ui.Model;
49 | import org.springframework.util.CollectionUtils;
50 | import org.springframework.web.bind.annotation.GetMapping;
51 | import org.springframework.web.client.RestTemplate;
52 | import org.springframework.web.servlet.ModelAndView;
53 | import org.springframework.web.util.UriComponentsBuilder;
54 |
55 | import lombok.RequiredArgsConstructor;
56 | import lombok.extern.slf4j.Slf4j;
57 |
58 | @SpringBootApplication
59 | public class SpringBoot2App {
60 |
61 | public static void main(String[] args) {
62 | SpringApplication.run(SpringBoot2App.class, args);
63 | }
64 | }
65 |
66 | @Configuration
67 | @EnableGlobalMethodSecurity(prePostEnabled = true)
68 | class WebSecurityConfig {
69 |
70 | @Bean
71 | public WebSecurityConfigurerAdapter webSecurityConfigurer( //
72 | @Value("${kc.realm}") String realm, //
73 | KeycloakOauth2UserService keycloakOidcUserService, //
74 | KeycloakLogoutHandler keycloakLogoutHandler //
75 | ) {
76 | return new WebSecurityConfigurerAdapter() {
77 | @Override
78 | public void configure(HttpSecurity http) throws Exception {
79 |
80 | http
81 | // Configure session management to your needs.
82 | // I need this as a basis for a classic, server side rendered application
83 | .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
84 | // Depends on your taste. You can configure single paths here
85 | // or allow everything a I did and then use method based security
86 | // like in the controller below
87 | .authorizeRequests().anyRequest().permitAll().and()
88 | // Propagate logouts via /logout to Keycloak
89 | .logout().addLogoutHandler(keycloakLogoutHandler).and()
90 | // This is the point where OAuth2 login of Spring 5 gets enabled
91 | .oauth2Login().userInfoEndpoint().oidcUserService(keycloakOidcUserService).and()
92 | // I don't want a page with different clients as login options
93 | // So i use the constant from OAuth2AuthorizationRequestRedirectFilter
94 | // plus the configured realm as immediate redirect to Keycloak
95 | .loginPage(DEFAULT_AUTHORIZATION_REQUEST_BASE_URI + "/" + realm);
96 | }
97 | };
98 | }
99 |
100 | @Bean
101 | KeycloakOauth2UserService keycloakOidcUserService(OAuth2ClientProperties oauth2ClientProperties) {
102 |
103 | // TODO use default JwtDecoder - where to grab?
104 | NimbusJwtDecoderJwkSupport jwtDecoder = new NimbusJwtDecoderJwkSupport(
105 | oauth2ClientProperties.getProvider().get("keycloak").getJwkSetUri());
106 |
107 | SimpleAuthorityMapper authoritiesMapper = new SimpleAuthorityMapper();
108 | authoritiesMapper.setConvertToUpperCase(true);
109 |
110 | return new KeycloakOauth2UserService(jwtDecoder, authoritiesMapper);
111 | }
112 |
113 | @Bean
114 | KeycloakLogoutHandler keycloakLogoutHandler() {
115 | return new KeycloakLogoutHandler(new RestTemplate());
116 | }
117 | }
118 |
119 | @RequiredArgsConstructor
120 | class KeycloakOauth2UserService extends OidcUserService {
121 |
122 | private final OAuth2Error INVALID_REQUEST = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST);
123 |
124 | private final JwtDecoder jwtDecoder;
125 |
126 | private final GrantedAuthoritiesMapper authoritiesMapper;
127 |
128 | /**
129 | * Augments {@link OidcUserService#loadUser(OidcUserRequest)} to add authorities
130 | * provided by Keycloak.
131 | *
132 | * Needed because {@link OidcUserService#loadUser(OidcUserRequest)} (currently)
133 | * does not provide a hook for adding custom authorities from a
134 | * {@link OidcUserRequest}.
135 | */
136 | @Override
137 | public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
138 |
139 | OidcUser user = super.loadUser(userRequest);
140 |
141 | Set authorities = new LinkedHashSet<>();
142 | authorities.addAll(user.getAuthorities());
143 | authorities.addAll(extractKeycloakAuthorities(userRequest));
144 |
145 | return new DefaultOidcUser(authorities, userRequest.getIdToken(), user.getUserInfo(), "preferred_username");
146 | }
147 |
148 | /**
149 | * Extracts {@link GrantedAuthority GrantedAuthorities} from the AccessToken in
150 | * the {@link OidcUserRequest}.
151 | *
152 | * @param userRequest
153 | * @return
154 | */
155 | private Collection extends GrantedAuthority> extractKeycloakAuthorities(OidcUserRequest userRequest) {
156 |
157 | Jwt token = parseJwt(userRequest.getAccessToken().getTokenValue());
158 |
159 | // Would be great if Spring Security would provide something like a plugable
160 | // OidcUserRequestAuthoritiesExtractor interface to hide the junk below...
161 |
162 | @SuppressWarnings("unchecked")
163 | Map resourceMap = (Map) token.getClaims().get("resource_access");
164 | String clientId = userRequest.getClientRegistration().getClientId();
165 |
166 | @SuppressWarnings("unchecked")
167 | Map> clientResource = (Map>) resourceMap.get(clientId);
168 | if (CollectionUtils.isEmpty(clientResource)) {
169 | return Collections.emptyList();
170 | }
171 |
172 | @SuppressWarnings("unchecked")
173 | List clientRoles = (List) clientResource.get("roles");
174 | if (CollectionUtils.isEmpty(clientRoles)) {
175 | return Collections.emptyList();
176 | }
177 |
178 | Collection extends GrantedAuthority> authorities = AuthorityUtils
179 | .createAuthorityList(clientRoles.toArray(new String[0]));
180 | if (authoritiesMapper == null) {
181 | return authorities;
182 | }
183 |
184 | return authoritiesMapper.mapAuthorities(authorities);
185 | }
186 |
187 | private Jwt parseJwt(String accessTokenValue) {
188 | try {
189 | // Token is already verified by spring security infrastructure
190 | return jwtDecoder.decode(accessTokenValue);
191 | } catch (JwtException e) {
192 | throw new OAuth2AuthenticationException(INVALID_REQUEST, e);
193 | }
194 | }
195 | }
196 |
197 | /**
198 | * Propagates logouts to Keycloak.
199 | *
200 | * Necessary because Spring Security 5 (currently) doesn't support
201 | * end-session-endpoints.
202 | */
203 | @Slf4j
204 | @RequiredArgsConstructor
205 | class KeycloakLogoutHandler extends SecurityContextLogoutHandler {
206 |
207 | private final RestTemplate restTemplate;
208 |
209 | @Override
210 | public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
211 | super.logout(request, response, authentication);
212 |
213 | propagateLogoutToKeycloak((OidcUser) authentication.getPrincipal());
214 | }
215 |
216 | private void propagateLogoutToKeycloak(OidcUser user) {
217 |
218 | String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout";
219 |
220 | UriComponentsBuilder builder = UriComponentsBuilder //
221 | .fromUriString(endSessionEndpoint) //
222 | .queryParam("id_token_hint", user.getIdToken().getTokenValue());
223 |
224 | ResponseEntity logoutResponse = restTemplate.getForEntity(builder.toUriString(), String.class);
225 | if (logoutResponse.getStatusCode().is2xxSuccessful()) {
226 | log.info("Successfulley logged out in Keycloak");
227 | } else {
228 | log.info("Could not propagate logout to Keycloak");
229 | }
230 | }
231 | }
232 |
233 | @Controller
234 | class DemoController {
235 |
236 | @PreAuthorize("hasRole('ROLE_USER')")
237 | @GetMapping("/protected")
238 | public ModelAndView protectedPage(Principal principal) {
239 | return new ModelAndView("app", Collections.singletonMap("principal", principal));
240 | }
241 |
242 | @PreAuthorize("hasRole('ROLE_ADMIN')")
243 | @GetMapping("/admin")
244 | public ModelAndView adminPage(Principal principal) {
245 | return new ModelAndView("admin", Collections.singletonMap("principal", principal));
246 | }
247 |
248 | @GetMapping("/")
249 | public String unprotectedPage(Model model, Principal principal) {
250 | model.addAttribute("principal", principal);
251 | return "index";
252 | }
253 |
254 | @GetMapping("/account")
255 | public String redirectToAccountPage(@AuthenticationPrincipal OAuth2AuthenticationToken authToken) {
256 |
257 | if (authToken == null) {
258 | return "redirect:/";
259 | }
260 |
261 | OidcUser user = (OidcUser) authToken.getPrincipal();
262 |
263 | // Provides a back-link to the application
264 | return "redirect:" + user.getIssuer() + "/account?referrer=" + user.getIdToken().getAuthorizedParty();
265 | }
266 | }
--------------------------------------------------------------------------------
/demo-realm.json:
--------------------------------------------------------------------------------
1 | {
2 | "id" : "demo",
3 | "realm" : "demo",
4 | "notBefore" : 0,
5 | "revokeRefreshToken" : false,
6 | "refreshTokenMaxReuse" : 0,
7 | "accessTokenLifespan" : 300,
8 | "accessTokenLifespanForImplicitFlow" : 900,
9 | "ssoSessionIdleTimeout" : 1800,
10 | "ssoSessionMaxLifespan" : 36000,
11 | "offlineSessionIdleTimeout" : 2592000,
12 | "accessCodeLifespan" : 60,
13 | "accessCodeLifespanUserAction" : 300,
14 | "accessCodeLifespanLogin" : 1800,
15 | "actionTokenGeneratedByAdminLifespan" : 43200,
16 | "actionTokenGeneratedByUserLifespan" : 300,
17 | "enabled" : true,
18 | "sslRequired" : "external",
19 | "registrationAllowed" : false,
20 | "registrationEmailAsUsername" : false,
21 | "rememberMe" : false,
22 | "verifyEmail" : false,
23 | "loginWithEmailAllowed" : true,
24 | "duplicateEmailsAllowed" : false,
25 | "resetPasswordAllowed" : false,
26 | "editUsernameAllowed" : false,
27 | "bruteForceProtected" : false,
28 | "permanentLockout" : false,
29 | "maxFailureWaitSeconds" : 900,
30 | "minimumQuickLoginWaitSeconds" : 60,
31 | "waitIncrementSeconds" : 60,
32 | "quickLoginCheckMilliSeconds" : 1000,
33 | "maxDeltaTimeSeconds" : 43200,
34 | "failureFactor" : 30,
35 | "roles" : {
36 | "realm" : [ {
37 | "id" : "9cec708f-b60c-4e72-87bd-bd6cc270804f",
38 | "name" : "offline_access",
39 | "description" : "${role_offline-access}",
40 | "scopeParamRequired" : true,
41 | "composite" : false,
42 | "clientRole" : false,
43 | "containerId" : "demo"
44 | }, {
45 | "id" : "b377ec00-d24e-481c-88d1-fc236fcbb4f8",
46 | "name" : "uma_authorization",
47 | "description" : "${role_uma_authorization}",
48 | "scopeParamRequired" : false,
49 | "composite" : false,
50 | "clientRole" : false,
51 | "containerId" : "demo"
52 | } ],
53 | "client" : {
54 | "realm-management" : [ {
55 | "id" : "e20d8308-6e6e-4814-8b6c-f31e429d83d8",
56 | "name" : "query-clients",
57 | "description" : "${role_query-clients}",
58 | "scopeParamRequired" : false,
59 | "composite" : false,
60 | "clientRole" : true,
61 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
62 | }, {
63 | "id" : "b64456f6-a12d-455d-8f91-5b2a508d1326",
64 | "name" : "view-identity-providers",
65 | "description" : "${role_view-identity-providers}",
66 | "scopeParamRequired" : false,
67 | "composite" : false,
68 | "clientRole" : true,
69 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
70 | }, {
71 | "id" : "968aa5a6-220f-4c73-a1d9-d1eb4b3f7f20",
72 | "name" : "query-groups",
73 | "description" : "${role_query-groups}",
74 | "scopeParamRequired" : false,
75 | "composite" : false,
76 | "clientRole" : true,
77 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
78 | }, {
79 | "id" : "54db3285-f76c-462f-9dea-3f0da29a8277",
80 | "name" : "view-events",
81 | "description" : "${role_view-events}",
82 | "scopeParamRequired" : false,
83 | "composite" : false,
84 | "clientRole" : true,
85 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
86 | }, {
87 | "id" : "f63004bf-394b-426f-b609-19ca807f3a57",
88 | "name" : "manage-users",
89 | "description" : "${role_manage-users}",
90 | "scopeParamRequired" : false,
91 | "composite" : false,
92 | "clientRole" : true,
93 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
94 | }, {
95 | "id" : "273b678a-2018-4480-9007-b0b5d318019e",
96 | "name" : "query-users",
97 | "description" : "${role_query-users}",
98 | "scopeParamRequired" : false,
99 | "composite" : false,
100 | "clientRole" : true,
101 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
102 | }, {
103 | "id" : "b0bcfe2c-e426-4cc8-8161-f6608203409b",
104 | "name" : "view-users",
105 | "description" : "${role_view-users}",
106 | "scopeParamRequired" : false,
107 | "composite" : true,
108 | "composites" : {
109 | "client" : {
110 | "realm-management" : [ "query-groups", "query-users" ]
111 | }
112 | },
113 | "clientRole" : true,
114 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
115 | }, {
116 | "id" : "4f2d2465-9e75-4975-8748-ec2bbb2f1b96",
117 | "name" : "query-realms",
118 | "description" : "${role_query-realms}",
119 | "scopeParamRequired" : false,
120 | "composite" : false,
121 | "clientRole" : true,
122 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
123 | }, {
124 | "id" : "65c72650-d874-4a6b-a065-4558a3e2fc6a",
125 | "name" : "create-client",
126 | "description" : "${role_create-client}",
127 | "scopeParamRequired" : false,
128 | "composite" : false,
129 | "clientRole" : true,
130 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
131 | }, {
132 | "id" : "a56996bc-9589-476b-9e54-88b5e6355fca",
133 | "name" : "manage-clients",
134 | "description" : "${role_manage-clients}",
135 | "scopeParamRequired" : false,
136 | "composite" : false,
137 | "clientRole" : true,
138 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
139 | }, {
140 | "id" : "6e8e2d8d-1632-4893-8428-3ec4c438bead",
141 | "name" : "view-clients",
142 | "description" : "${role_view-clients}",
143 | "scopeParamRequired" : false,
144 | "composite" : true,
145 | "composites" : {
146 | "client" : {
147 | "realm-management" : [ "query-clients" ]
148 | }
149 | },
150 | "clientRole" : true,
151 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
152 | }, {
153 | "id" : "25c953c3-a411-4237-8501-7b8ebef5988f",
154 | "name" : "manage-realm",
155 | "description" : "${role_manage-realm}",
156 | "scopeParamRequired" : false,
157 | "composite" : false,
158 | "clientRole" : true,
159 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
160 | }, {
161 | "id" : "dc1a53ec-d0e1-441f-8e72-8ca411ab21a0",
162 | "name" : "view-authorization",
163 | "description" : "${role_view-authorization}",
164 | "scopeParamRequired" : false,
165 | "composite" : false,
166 | "clientRole" : true,
167 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
168 | }, {
169 | "id" : "30bbf430-98a6-46d5-a25c-48992aebd848",
170 | "name" : "realm-admin",
171 | "description" : "${role_realm-admin}",
172 | "scopeParamRequired" : false,
173 | "composite" : true,
174 | "composites" : {
175 | "client" : {
176 | "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" ]
177 | }
178 | },
179 | "clientRole" : true,
180 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
181 | }, {
182 | "id" : "2f93f784-ece8-4205-a9c2-b933b6beee09",
183 | "name" : "manage-events",
184 | "description" : "${role_manage-events}",
185 | "scopeParamRequired" : false,
186 | "composite" : false,
187 | "clientRole" : true,
188 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
189 | }, {
190 | "id" : "eb6ab687-958a-4c24-a97d-569e31101c41",
191 | "name" : "manage-authorization",
192 | "description" : "${role_manage-authorization}",
193 | "scopeParamRequired" : false,
194 | "composite" : false,
195 | "clientRole" : true,
196 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
197 | }, {
198 | "id" : "e4d149d9-5c8e-4f1c-9a40-ac371aaf3794",
199 | "name" : "impersonation",
200 | "description" : "${role_impersonation}",
201 | "scopeParamRequired" : false,
202 | "composite" : false,
203 | "clientRole" : true,
204 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
205 | }, {
206 | "id" : "3f9d491f-7df0-4f91-ab0d-5f5531b41f9d",
207 | "name" : "view-realm",
208 | "description" : "${role_view-realm}",
209 | "scopeParamRequired" : false,
210 | "composite" : false,
211 | "clientRole" : true,
212 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
213 | }, {
214 | "id" : "11ba2522-4090-431b-9842-0e9f31884d0a",
215 | "name" : "manage-identity-providers",
216 | "description" : "${role_manage-identity-providers}",
217 | "scopeParamRequired" : false,
218 | "composite" : false,
219 | "clientRole" : true,
220 | "containerId" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd"
221 | } ],
222 | "security-admin-console" : [ ],
223 | "admin-cli" : [ ],
224 | "app-demo" : [ {
225 | "id" : "57b84603-ceef-4a48-bd08-f46467eb7bd9",
226 | "name" : "admin",
227 | "scopeParamRequired" : false,
228 | "composite" : false,
229 | "clientRole" : true,
230 | "containerId" : "ec2975dc-bde7-4012-89c4-06a499c00235"
231 | }, {
232 | "id" : "754c1364-9444-4477-bcc1-b07794bee2fc",
233 | "name" : "user",
234 | "scopeParamRequired" : false,
235 | "composite" : false,
236 | "clientRole" : true,
237 | "containerId" : "ec2975dc-bde7-4012-89c4-06a499c00235"
238 | } ],
239 | "broker" : [ {
240 | "id" : "f08f6cf6-09ed-41f6-9c05-164dc8f8ab5e",
241 | "name" : "read-token",
242 | "description" : "${role_read-token}",
243 | "scopeParamRequired" : false,
244 | "composite" : false,
245 | "clientRole" : true,
246 | "containerId" : "0536d12c-2c36-444a-898b-ed7b527aac76"
247 | } ],
248 | "account" : [ {
249 | "id" : "c4cf29c5-3375-45d1-acd2-5962af1c733a",
250 | "name" : "manage-account",
251 | "description" : "${role_manage-account}",
252 | "scopeParamRequired" : false,
253 | "composite" : true,
254 | "composites" : {
255 | "client" : {
256 | "account" : [ "manage-account-links" ]
257 | }
258 | },
259 | "clientRole" : true,
260 | "containerId" : "2e441b12-8370-49b8-b8aa-2c7546144b4e"
261 | }, {
262 | "id" : "5d703753-792e-4167-ad2b-c5b7f6a959d7",
263 | "name" : "view-profile",
264 | "description" : "${role_view-profile}",
265 | "scopeParamRequired" : false,
266 | "composite" : false,
267 | "clientRole" : true,
268 | "containerId" : "2e441b12-8370-49b8-b8aa-2c7546144b4e"
269 | }, {
270 | "id" : "8eb0ae88-2819-47ab-9a93-6ff34b43ae88",
271 | "name" : "manage-account-links",
272 | "description" : "${role_manage-account-links}",
273 | "scopeParamRequired" : false,
274 | "composite" : false,
275 | "clientRole" : true,
276 | "containerId" : "2e441b12-8370-49b8-b8aa-2c7546144b4e"
277 | } ]
278 | }
279 | },
280 | "groups" : [ ],
281 | "defaultRoles" : [ "offline_access", "uma_authorization" ],
282 | "requiredCredentials" : [ "password" ],
283 | "otpPolicyType" : "totp",
284 | "otpPolicyAlgorithm" : "HmacSHA1",
285 | "otpPolicyInitialCounter" : 0,
286 | "otpPolicyDigits" : 6,
287 | "otpPolicyLookAheadWindow" : 1,
288 | "otpPolicyPeriod" : 30,
289 | "otpSupportedApplications" : [ "FreeOTP", "Google Authenticator" ],
290 | "users" : [ {
291 | "id" : "8d7a7207-94c0-4ba7-ac3a-efb79412dd44",
292 | "createdTimestamp" : 1523988975613,
293 | "username" : "admin",
294 | "enabled" : true,
295 | "totp" : false,
296 | "emailVerified" : false,
297 | "firstName" : "Arno",
298 | "lastName" : "Admin",
299 | "email" : "tom+admin@localhost",
300 | "credentials" : [ {
301 | "type" : "password",
302 | "hashedSaltedValue" : "ZcC45qA9JiFQYuJau1w/pxfBmZusDDoCO0Sx4z+uFWdE4CA1FUibOqpqHh21GwRKcdRSseqrBBaaPbBznIWYRQ==",
303 | "salt" : "sTMbn/fDpC/KX549o9XoHg==",
304 | "hashIterations" : 27500,
305 | "counter" : 0,
306 | "algorithm" : "pbkdf2-sha256",
307 | "digits" : 0,
308 | "period" : 0,
309 | "createdDate" : 1523988982527,
310 | "config" : { }
311 | } ],
312 | "disableableCredentialTypes" : [ "password" ],
313 | "requiredActions" : [ ],
314 | "realmRoles" : [ "offline_access", "uma_authorization" ],
315 | "clientRoles" : {
316 | "app-demo" : [ "admin", "user" ],
317 | "account" : [ "manage-account", "view-profile" ]
318 | },
319 | "notBefore" : 0,
320 | "groups" : [ ]
321 | }, {
322 | "id" : "91591318-6c82-4250-b6fb-9a5e257959a5",
323 | "createdTimestamp" : 1523983635756,
324 | "username" : "tester",
325 | "enabled" : true,
326 | "totp" : false,
327 | "emailVerified" : false,
328 | "firstName" : "Theo",
329 | "lastName" : "Tester",
330 | "email" : "tom+test@localhost",
331 | "credentials" : [ {
332 | "type" : "password",
333 | "hashedSaltedValue" : "h/aCiQS3fdB/euTSwOz/ww/+L0b6c9WGsRsMMSPr899rQIFLlIhjWjAgA9BbRAKsSLfo+nsNUKaXGfhwgi2r7g==",
334 | "salt" : "W3mOjqoG8mctglGSgbYSKQ==",
335 | "hashIterations" : 27500,
336 | "counter" : 0,
337 | "algorithm" : "pbkdf2-sha256",
338 | "digits" : 0,
339 | "period" : 0,
340 | "createdDate" : 1523983645059,
341 | "config" : { }
342 | } ],
343 | "disableableCredentialTypes" : [ "password" ],
344 | "requiredActions" : [ ],
345 | "realmRoles" : [ "offline_access", "uma_authorization" ],
346 | "clientRoles" : {
347 | "app-demo" : [ "user" ],
348 | "account" : [ "manage-account", "view-profile" ]
349 | },
350 | "notBefore" : 0,
351 | "groups" : [ ]
352 | } ],
353 | "clients" : [ {
354 | "id" : "2e441b12-8370-49b8-b8aa-2c7546144b4e",
355 | "clientId" : "account",
356 | "name" : "${client_account}",
357 | "baseUrl" : "/auth/realms/demo/account",
358 | "surrogateAuthRequired" : false,
359 | "enabled" : true,
360 | "clientAuthenticatorType" : "client-secret",
361 | "secret" : "85e4ed69-3da1-4d34-ba4e-31980b4b386d",
362 | "defaultRoles" : [ "view-profile", "manage-account" ],
363 | "redirectUris" : [ "/auth/realms/demo/account/*" ],
364 | "webOrigins" : [ ],
365 | "notBefore" : 0,
366 | "bearerOnly" : false,
367 | "consentRequired" : false,
368 | "standardFlowEnabled" : true,
369 | "implicitFlowEnabled" : false,
370 | "directAccessGrantsEnabled" : false,
371 | "serviceAccountsEnabled" : false,
372 | "publicClient" : false,
373 | "frontchannelLogout" : false,
374 | "protocol" : "openid-connect",
375 | "attributes" : { },
376 | "fullScopeAllowed" : false,
377 | "nodeReRegistrationTimeout" : 0,
378 | "protocolMappers" : [ {
379 | "id" : "61173bf1-f182-4c08-81f1-45ded5285a96",
380 | "name" : "given name",
381 | "protocol" : "openid-connect",
382 | "protocolMapper" : "oidc-usermodel-property-mapper",
383 | "consentRequired" : true,
384 | "consentText" : "${givenName}",
385 | "config" : {
386 | "userinfo.token.claim" : "true",
387 | "user.attribute" : "firstName",
388 | "id.token.claim" : "true",
389 | "access.token.claim" : "true",
390 | "claim.name" : "given_name",
391 | "jsonType.label" : "String"
392 | }
393 | }, {
394 | "id" : "3fc7edb3-23e1-4211-9a71-61700c849841",
395 | "name" : "family name",
396 | "protocol" : "openid-connect",
397 | "protocolMapper" : "oidc-usermodel-property-mapper",
398 | "consentRequired" : true,
399 | "consentText" : "${familyName}",
400 | "config" : {
401 | "userinfo.token.claim" : "true",
402 | "user.attribute" : "lastName",
403 | "id.token.claim" : "true",
404 | "access.token.claim" : "true",
405 | "claim.name" : "family_name",
406 | "jsonType.label" : "String"
407 | }
408 | }, {
409 | "id" : "33bcaadd-4cae-44fd-8f53-cfbb9b1804a3",
410 | "name" : "email",
411 | "protocol" : "openid-connect",
412 | "protocolMapper" : "oidc-usermodel-property-mapper",
413 | "consentRequired" : true,
414 | "consentText" : "${email}",
415 | "config" : {
416 | "userinfo.token.claim" : "true",
417 | "user.attribute" : "email",
418 | "id.token.claim" : "true",
419 | "access.token.claim" : "true",
420 | "claim.name" : "email",
421 | "jsonType.label" : "String"
422 | }
423 | }, {
424 | "id" : "b7ea4f28-5d0c-4ec3-b03f-bef776943c65",
425 | "name" : "username",
426 | "protocol" : "openid-connect",
427 | "protocolMapper" : "oidc-usermodel-property-mapper",
428 | "consentRequired" : true,
429 | "consentText" : "${username}",
430 | "config" : {
431 | "userinfo.token.claim" : "true",
432 | "user.attribute" : "username",
433 | "id.token.claim" : "true",
434 | "access.token.claim" : "true",
435 | "claim.name" : "preferred_username",
436 | "jsonType.label" : "String"
437 | }
438 | }, {
439 | "id" : "493cb2a0-3b7d-46de-9aa4-e9b36e9b75c5",
440 | "name" : "role list",
441 | "protocol" : "saml",
442 | "protocolMapper" : "saml-role-list-mapper",
443 | "consentRequired" : false,
444 | "config" : {
445 | "single" : "false",
446 | "attribute.nameformat" : "Basic",
447 | "attribute.name" : "Role"
448 | }
449 | }, {
450 | "id" : "f2e9d26c-4703-4fac-b5d5-cbbb8cbf9fbc",
451 | "name" : "full name",
452 | "protocol" : "openid-connect",
453 | "protocolMapper" : "oidc-full-name-mapper",
454 | "consentRequired" : true,
455 | "consentText" : "${fullName}",
456 | "config" : {
457 | "id.token.claim" : "true",
458 | "access.token.claim" : "true"
459 | }
460 | } ],
461 | "useTemplateConfig" : false,
462 | "useTemplateScope" : false,
463 | "useTemplateMappers" : false
464 | }, {
465 | "id" : "c0d68b59-146c-462e-910d-eae82c190c61",
466 | "clientId" : "admin-cli",
467 | "name" : "${client_admin-cli}",
468 | "surrogateAuthRequired" : false,
469 | "enabled" : true,
470 | "clientAuthenticatorType" : "client-secret",
471 | "secret" : "e4491867-8a42-4ca4-93ee-34a898ea6775",
472 | "redirectUris" : [ ],
473 | "webOrigins" : [ ],
474 | "notBefore" : 0,
475 | "bearerOnly" : false,
476 | "consentRequired" : false,
477 | "standardFlowEnabled" : false,
478 | "implicitFlowEnabled" : false,
479 | "directAccessGrantsEnabled" : true,
480 | "serviceAccountsEnabled" : false,
481 | "publicClient" : true,
482 | "frontchannelLogout" : false,
483 | "protocol" : "openid-connect",
484 | "attributes" : { },
485 | "fullScopeAllowed" : false,
486 | "nodeReRegistrationTimeout" : 0,
487 | "protocolMappers" : [ {
488 | "id" : "e005a327-9dcb-447d-80c2-f7c668d0afaa",
489 | "name" : "full name",
490 | "protocol" : "openid-connect",
491 | "protocolMapper" : "oidc-full-name-mapper",
492 | "consentRequired" : true,
493 | "consentText" : "${fullName}",
494 | "config" : {
495 | "id.token.claim" : "true",
496 | "access.token.claim" : "true"
497 | }
498 | }, {
499 | "id" : "a4cab9da-4684-4bdb-8351-abf2d9428845",
500 | "name" : "given name",
501 | "protocol" : "openid-connect",
502 | "protocolMapper" : "oidc-usermodel-property-mapper",
503 | "consentRequired" : true,
504 | "consentText" : "${givenName}",
505 | "config" : {
506 | "userinfo.token.claim" : "true",
507 | "user.attribute" : "firstName",
508 | "id.token.claim" : "true",
509 | "access.token.claim" : "true",
510 | "claim.name" : "given_name",
511 | "jsonType.label" : "String"
512 | }
513 | }, {
514 | "id" : "b2fc3109-62de-4b87-8c31-29e895329f93",
515 | "name" : "family name",
516 | "protocol" : "openid-connect",
517 | "protocolMapper" : "oidc-usermodel-property-mapper",
518 | "consentRequired" : true,
519 | "consentText" : "${familyName}",
520 | "config" : {
521 | "userinfo.token.claim" : "true",
522 | "user.attribute" : "lastName",
523 | "id.token.claim" : "true",
524 | "access.token.claim" : "true",
525 | "claim.name" : "family_name",
526 | "jsonType.label" : "String"
527 | }
528 | }, {
529 | "id" : "90622937-00bc-4e2e-a5d6-3f573712b2d2",
530 | "name" : "username",
531 | "protocol" : "openid-connect",
532 | "protocolMapper" : "oidc-usermodel-property-mapper",
533 | "consentRequired" : true,
534 | "consentText" : "${username}",
535 | "config" : {
536 | "userinfo.token.claim" : "true",
537 | "user.attribute" : "username",
538 | "id.token.claim" : "true",
539 | "access.token.claim" : "true",
540 | "claim.name" : "preferred_username",
541 | "jsonType.label" : "String"
542 | }
543 | }, {
544 | "id" : "4960d696-da1f-4fd2-8e15-49cdad809b03",
545 | "name" : "email",
546 | "protocol" : "openid-connect",
547 | "protocolMapper" : "oidc-usermodel-property-mapper",
548 | "consentRequired" : true,
549 | "consentText" : "${email}",
550 | "config" : {
551 | "userinfo.token.claim" : "true",
552 | "user.attribute" : "email",
553 | "id.token.claim" : "true",
554 | "access.token.claim" : "true",
555 | "claim.name" : "email",
556 | "jsonType.label" : "String"
557 | }
558 | }, {
559 | "id" : "c175c2f3-d399-4171-a46a-ac74a5b835f0",
560 | "name" : "role list",
561 | "protocol" : "saml",
562 | "protocolMapper" : "saml-role-list-mapper",
563 | "consentRequired" : false,
564 | "config" : {
565 | "single" : "false",
566 | "attribute.nameformat" : "Basic",
567 | "attribute.name" : "Role"
568 | }
569 | } ],
570 | "useTemplateConfig" : false,
571 | "useTemplateScope" : false,
572 | "useTemplateMappers" : false
573 | }, {
574 | "id" : "ec2975dc-bde7-4012-89c4-06a499c00235",
575 | "clientId" : "app-demo",
576 | "baseUrl" : "http://localhost:8082/",
577 | "surrogateAuthRequired" : false,
578 | "enabled" : true,
579 | "clientAuthenticatorType" : "client-secret",
580 | "secret" : "e3f519b4-0272-4261-9912-8b7453ac4ecd",
581 | "redirectUris" : [ "http://localhost:8082/*" ],
582 | "webOrigins" : [ "http://localhost:8082" ],
583 | "notBefore" : 0,
584 | "bearerOnly" : false,
585 | "consentRequired" : false,
586 | "standardFlowEnabled" : true,
587 | "implicitFlowEnabled" : false,
588 | "directAccessGrantsEnabled" : true,
589 | "serviceAccountsEnabled" : false,
590 | "publicClient" : false,
591 | "frontchannelLogout" : false,
592 | "protocol" : "openid-connect",
593 | "attributes" : {
594 | "saml.assertion.signature" : "false",
595 | "saml.force.post.binding" : "false",
596 | "saml.multivalued.roles" : "false",
597 | "saml.encrypt" : "false",
598 | "saml_force_name_id_format" : "false",
599 | "saml.client.signature" : "false",
600 | "saml.authnstatement" : "false",
601 | "saml.server.signature" : "false",
602 | "saml.server.signature.keyinfo.ext" : "false",
603 | "saml.onetimeuse.condition" : "false"
604 | },
605 | "fullScopeAllowed" : true,
606 | "nodeReRegistrationTimeout" : -1,
607 | "protocolMappers" : [ {
608 | "id" : "f632a9a7-5cff-4254-9941-82fabfdb3216",
609 | "name" : "role list",
610 | "protocol" : "saml",
611 | "protocolMapper" : "saml-role-list-mapper",
612 | "consentRequired" : false,
613 | "config" : {
614 | "single" : "false",
615 | "attribute.nameformat" : "Basic",
616 | "attribute.name" : "Role"
617 | }
618 | }, {
619 | "id" : "488d9ab7-7585-41dc-9d09-dd6d639b7a24",
620 | "name" : "username",
621 | "protocol" : "openid-connect",
622 | "protocolMapper" : "oidc-usermodel-property-mapper",
623 | "consentRequired" : true,
624 | "consentText" : "${username}",
625 | "config" : {
626 | "userinfo.token.claim" : "true",
627 | "user.attribute" : "username",
628 | "id.token.claim" : "true",
629 | "access.token.claim" : "true",
630 | "claim.name" : "preferred_username",
631 | "jsonType.label" : "String"
632 | }
633 | }, {
634 | "id" : "de28c7ae-a613-4f9d-8edb-1b9aa507efb9",
635 | "name" : "email",
636 | "protocol" : "openid-connect",
637 | "protocolMapper" : "oidc-usermodel-property-mapper",
638 | "consentRequired" : true,
639 | "consentText" : "${email}",
640 | "config" : {
641 | "userinfo.token.claim" : "true",
642 | "user.attribute" : "email",
643 | "id.token.claim" : "true",
644 | "access.token.claim" : "true",
645 | "claim.name" : "email",
646 | "jsonType.label" : "String"
647 | }
648 | }, {
649 | "id" : "6611aecf-daad-4ad2-aa74-c33de47037b0",
650 | "name" : "full name",
651 | "protocol" : "openid-connect",
652 | "protocolMapper" : "oidc-full-name-mapper",
653 | "consentRequired" : true,
654 | "consentText" : "${fullName}",
655 | "config" : {
656 | "id.token.claim" : "true",
657 | "access.token.claim" : "true"
658 | }
659 | }, {
660 | "id" : "cb5a11ce-3311-4a78-9061-e6221184b6f5",
661 | "name" : "given name",
662 | "protocol" : "openid-connect",
663 | "protocolMapper" : "oidc-usermodel-property-mapper",
664 | "consentRequired" : true,
665 | "consentText" : "${givenName}",
666 | "config" : {
667 | "userinfo.token.claim" : "true",
668 | "user.attribute" : "firstName",
669 | "id.token.claim" : "true",
670 | "access.token.claim" : "true",
671 | "claim.name" : "given_name",
672 | "jsonType.label" : "String"
673 | }
674 | }, {
675 | "id" : "4ec046bf-9c35-44ac-9395-fcda434fc061",
676 | "name" : "family name",
677 | "protocol" : "openid-connect",
678 | "protocolMapper" : "oidc-usermodel-property-mapper",
679 | "consentRequired" : true,
680 | "consentText" : "${familyName}",
681 | "config" : {
682 | "userinfo.token.claim" : "true",
683 | "user.attribute" : "lastName",
684 | "id.token.claim" : "true",
685 | "access.token.claim" : "true",
686 | "claim.name" : "family_name",
687 | "jsonType.label" : "String"
688 | }
689 | } ],
690 | "useTemplateConfig" : false,
691 | "useTemplateScope" : false,
692 | "useTemplateMappers" : false
693 | }, {
694 | "id" : "0536d12c-2c36-444a-898b-ed7b527aac76",
695 | "clientId" : "broker",
696 | "name" : "${client_broker}",
697 | "surrogateAuthRequired" : false,
698 | "enabled" : true,
699 | "clientAuthenticatorType" : "client-secret",
700 | "secret" : "577625be-1736-4bee-9bb2-608aff465c64",
701 | "redirectUris" : [ ],
702 | "webOrigins" : [ ],
703 | "notBefore" : 0,
704 | "bearerOnly" : false,
705 | "consentRequired" : false,
706 | "standardFlowEnabled" : true,
707 | "implicitFlowEnabled" : false,
708 | "directAccessGrantsEnabled" : false,
709 | "serviceAccountsEnabled" : false,
710 | "publicClient" : false,
711 | "frontchannelLogout" : false,
712 | "protocol" : "openid-connect",
713 | "attributes" : { },
714 | "fullScopeAllowed" : false,
715 | "nodeReRegistrationTimeout" : 0,
716 | "protocolMappers" : [ {
717 | "id" : "5f5e550c-ff29-482d-bb1f-0215d6bf081d",
718 | "name" : "family name",
719 | "protocol" : "openid-connect",
720 | "protocolMapper" : "oidc-usermodel-property-mapper",
721 | "consentRequired" : true,
722 | "consentText" : "${familyName}",
723 | "config" : {
724 | "userinfo.token.claim" : "true",
725 | "user.attribute" : "lastName",
726 | "id.token.claim" : "true",
727 | "access.token.claim" : "true",
728 | "claim.name" : "family_name",
729 | "jsonType.label" : "String"
730 | }
731 | }, {
732 | "id" : "9239d7be-795f-4307-b0fe-ae0635fc367f",
733 | "name" : "full name",
734 | "protocol" : "openid-connect",
735 | "protocolMapper" : "oidc-full-name-mapper",
736 | "consentRequired" : true,
737 | "consentText" : "${fullName}",
738 | "config" : {
739 | "id.token.claim" : "true",
740 | "access.token.claim" : "true"
741 | }
742 | }, {
743 | "id" : "c7be1c7e-a0d2-4fe3-869c-de00d694f067",
744 | "name" : "email",
745 | "protocol" : "openid-connect",
746 | "protocolMapper" : "oidc-usermodel-property-mapper",
747 | "consentRequired" : true,
748 | "consentText" : "${email}",
749 | "config" : {
750 | "userinfo.token.claim" : "true",
751 | "user.attribute" : "email",
752 | "id.token.claim" : "true",
753 | "access.token.claim" : "true",
754 | "claim.name" : "email",
755 | "jsonType.label" : "String"
756 | }
757 | }, {
758 | "id" : "e0c76ba5-d83d-4366-9b16-7b334fa587d4",
759 | "name" : "role list",
760 | "protocol" : "saml",
761 | "protocolMapper" : "saml-role-list-mapper",
762 | "consentRequired" : false,
763 | "config" : {
764 | "single" : "false",
765 | "attribute.nameformat" : "Basic",
766 | "attribute.name" : "Role"
767 | }
768 | }, {
769 | "id" : "d97fa215-8d04-466b-8c19-a7c5f14ed1fa",
770 | "name" : "username",
771 | "protocol" : "openid-connect",
772 | "protocolMapper" : "oidc-usermodel-property-mapper",
773 | "consentRequired" : true,
774 | "consentText" : "${username}",
775 | "config" : {
776 | "userinfo.token.claim" : "true",
777 | "user.attribute" : "username",
778 | "id.token.claim" : "true",
779 | "access.token.claim" : "true",
780 | "claim.name" : "preferred_username",
781 | "jsonType.label" : "String"
782 | }
783 | }, {
784 | "id" : "b5359a60-d80b-4c5d-aa7c-ff3d1959aa9b",
785 | "name" : "given name",
786 | "protocol" : "openid-connect",
787 | "protocolMapper" : "oidc-usermodel-property-mapper",
788 | "consentRequired" : true,
789 | "consentText" : "${givenName}",
790 | "config" : {
791 | "userinfo.token.claim" : "true",
792 | "user.attribute" : "firstName",
793 | "id.token.claim" : "true",
794 | "access.token.claim" : "true",
795 | "claim.name" : "given_name",
796 | "jsonType.label" : "String"
797 | }
798 | } ],
799 | "useTemplateConfig" : false,
800 | "useTemplateScope" : false,
801 | "useTemplateMappers" : false
802 | }, {
803 | "id" : "4e57a54d-42c8-400e-9cc1-95a36fbe02fd",
804 | "clientId" : "realm-management",
805 | "name" : "${client_realm-management}",
806 | "surrogateAuthRequired" : false,
807 | "enabled" : true,
808 | "clientAuthenticatorType" : "client-secret",
809 | "secret" : "05f5e2a2-83c9-45be-bc8b-7d9c2a924ed4",
810 | "redirectUris" : [ ],
811 | "webOrigins" : [ ],
812 | "notBefore" : 0,
813 | "bearerOnly" : true,
814 | "consentRequired" : false,
815 | "standardFlowEnabled" : true,
816 | "implicitFlowEnabled" : false,
817 | "directAccessGrantsEnabled" : false,
818 | "serviceAccountsEnabled" : false,
819 | "publicClient" : false,
820 | "frontchannelLogout" : false,
821 | "protocol" : "openid-connect",
822 | "attributes" : { },
823 | "fullScopeAllowed" : false,
824 | "nodeReRegistrationTimeout" : 0,
825 | "protocolMappers" : [ {
826 | "id" : "b699f558-b852-4013-a8c2-177abf9a8353",
827 | "name" : "full name",
828 | "protocol" : "openid-connect",
829 | "protocolMapper" : "oidc-full-name-mapper",
830 | "consentRequired" : true,
831 | "consentText" : "${fullName}",
832 | "config" : {
833 | "id.token.claim" : "true",
834 | "access.token.claim" : "true"
835 | }
836 | }, {
837 | "id" : "1377d3f0-8587-4458-8252-1f740f00dbe1",
838 | "name" : "email",
839 | "protocol" : "openid-connect",
840 | "protocolMapper" : "oidc-usermodel-property-mapper",
841 | "consentRequired" : true,
842 | "consentText" : "${email}",
843 | "config" : {
844 | "userinfo.token.claim" : "true",
845 | "user.attribute" : "email",
846 | "id.token.claim" : "true",
847 | "access.token.claim" : "true",
848 | "claim.name" : "email",
849 | "jsonType.label" : "String"
850 | }
851 | }, {
852 | "id" : "ca0e2b5c-6580-4949-80bd-fb3b87a0c7b5",
853 | "name" : "role list",
854 | "protocol" : "saml",
855 | "protocolMapper" : "saml-role-list-mapper",
856 | "consentRequired" : false,
857 | "config" : {
858 | "single" : "false",
859 | "attribute.nameformat" : "Basic",
860 | "attribute.name" : "Role"
861 | }
862 | }, {
863 | "id" : "101f9558-3e9c-4f34-b11b-b7e9f6ee7645",
864 | "name" : "family name",
865 | "protocol" : "openid-connect",
866 | "protocolMapper" : "oidc-usermodel-property-mapper",
867 | "consentRequired" : true,
868 | "consentText" : "${familyName}",
869 | "config" : {
870 | "userinfo.token.claim" : "true",
871 | "user.attribute" : "lastName",
872 | "id.token.claim" : "true",
873 | "access.token.claim" : "true",
874 | "claim.name" : "family_name",
875 | "jsonType.label" : "String"
876 | }
877 | }, {
878 | "id" : "be6fa79f-ade5-44c9-afa0-93b8170c47b9",
879 | "name" : "username",
880 | "protocol" : "openid-connect",
881 | "protocolMapper" : "oidc-usermodel-property-mapper",
882 | "consentRequired" : true,
883 | "consentText" : "${username}",
884 | "config" : {
885 | "userinfo.token.claim" : "true",
886 | "user.attribute" : "username",
887 | "id.token.claim" : "true",
888 | "access.token.claim" : "true",
889 | "claim.name" : "preferred_username",
890 | "jsonType.label" : "String"
891 | }
892 | }, {
893 | "id" : "b5d07f15-6a26-4350-9bf9-54d5359c0706",
894 | "name" : "given name",
895 | "protocol" : "openid-connect",
896 | "protocolMapper" : "oidc-usermodel-property-mapper",
897 | "consentRequired" : true,
898 | "consentText" : "${givenName}",
899 | "config" : {
900 | "userinfo.token.claim" : "true",
901 | "user.attribute" : "firstName",
902 | "id.token.claim" : "true",
903 | "access.token.claim" : "true",
904 | "claim.name" : "given_name",
905 | "jsonType.label" : "String"
906 | }
907 | } ],
908 | "useTemplateConfig" : false,
909 | "useTemplateScope" : false,
910 | "useTemplateMappers" : false
911 | }, {
912 | "id" : "8878b917-5b73-4950-b014-8100b0c405ed",
913 | "clientId" : "security-admin-console",
914 | "name" : "${client_security-admin-console}",
915 | "baseUrl" : "/auth/admin/demo/console/index.html",
916 | "surrogateAuthRequired" : false,
917 | "enabled" : true,
918 | "clientAuthenticatorType" : "client-secret",
919 | "secret" : "351b34ac-3a0f-4f09-af5a-6b9278c09b85",
920 | "redirectUris" : [ "/auth/admin/demo/console/*" ],
921 | "webOrigins" : [ ],
922 | "notBefore" : 0,
923 | "bearerOnly" : false,
924 | "consentRequired" : false,
925 | "standardFlowEnabled" : true,
926 | "implicitFlowEnabled" : false,
927 | "directAccessGrantsEnabled" : false,
928 | "serviceAccountsEnabled" : false,
929 | "publicClient" : true,
930 | "frontchannelLogout" : false,
931 | "protocol" : "openid-connect",
932 | "attributes" : { },
933 | "fullScopeAllowed" : false,
934 | "nodeReRegistrationTimeout" : 0,
935 | "protocolMappers" : [ {
936 | "id" : "9a97567c-d9d6-4f5c-8d0f-ed1e060e598a",
937 | "name" : "role list",
938 | "protocol" : "saml",
939 | "protocolMapper" : "saml-role-list-mapper",
940 | "consentRequired" : false,
941 | "config" : {
942 | "single" : "false",
943 | "attribute.nameformat" : "Basic",
944 | "attribute.name" : "Role"
945 | }
946 | }, {
947 | "id" : "6dae9b5b-0948-4591-a69f-51a1590e892f",
948 | "name" : "username",
949 | "protocol" : "openid-connect",
950 | "protocolMapper" : "oidc-usermodel-property-mapper",
951 | "consentRequired" : true,
952 | "consentText" : "${username}",
953 | "config" : {
954 | "userinfo.token.claim" : "true",
955 | "user.attribute" : "username",
956 | "id.token.claim" : "true",
957 | "access.token.claim" : "true",
958 | "claim.name" : "preferred_username",
959 | "jsonType.label" : "String"
960 | }
961 | }, {
962 | "id" : "085240de-a1c4-4735-af6a-2c565e9612cf",
963 | "name" : "email",
964 | "protocol" : "openid-connect",
965 | "protocolMapper" : "oidc-usermodel-property-mapper",
966 | "consentRequired" : true,
967 | "consentText" : "${email}",
968 | "config" : {
969 | "userinfo.token.claim" : "true",
970 | "user.attribute" : "email",
971 | "id.token.claim" : "true",
972 | "access.token.claim" : "true",
973 | "claim.name" : "email",
974 | "jsonType.label" : "String"
975 | }
976 | }, {
977 | "id" : "594a456d-2cdb-49a3-8c40-05145a406f92",
978 | "name" : "family name",
979 | "protocol" : "openid-connect",
980 | "protocolMapper" : "oidc-usermodel-property-mapper",
981 | "consentRequired" : true,
982 | "consentText" : "${familyName}",
983 | "config" : {
984 | "userinfo.token.claim" : "true",
985 | "user.attribute" : "lastName",
986 | "id.token.claim" : "true",
987 | "access.token.claim" : "true",
988 | "claim.name" : "family_name",
989 | "jsonType.label" : "String"
990 | }
991 | }, {
992 | "id" : "00f77d41-e3d3-443d-9e0f-098379d88ca7",
993 | "name" : "given name",
994 | "protocol" : "openid-connect",
995 | "protocolMapper" : "oidc-usermodel-property-mapper",
996 | "consentRequired" : true,
997 | "consentText" : "${givenName}",
998 | "config" : {
999 | "userinfo.token.claim" : "true",
1000 | "user.attribute" : "firstName",
1001 | "id.token.claim" : "true",
1002 | "access.token.claim" : "true",
1003 | "claim.name" : "given_name",
1004 | "jsonType.label" : "String"
1005 | }
1006 | }, {
1007 | "id" : "b12cbc25-fe43-4597-84e5-77b506712186",
1008 | "name" : "full name",
1009 | "protocol" : "openid-connect",
1010 | "protocolMapper" : "oidc-full-name-mapper",
1011 | "consentRequired" : true,
1012 | "consentText" : "${fullName}",
1013 | "config" : {
1014 | "id.token.claim" : "true",
1015 | "access.token.claim" : "true"
1016 | }
1017 | }, {
1018 | "id" : "08f6ee38-4048-407a-8baa-a2e770ae5123",
1019 | "name" : "locale",
1020 | "protocol" : "openid-connect",
1021 | "protocolMapper" : "oidc-usermodel-attribute-mapper",
1022 | "consentRequired" : false,
1023 | "consentText" : "${locale}",
1024 | "config" : {
1025 | "userinfo.token.claim" : "true",
1026 | "user.attribute" : "locale",
1027 | "id.token.claim" : "true",
1028 | "access.token.claim" : "true",
1029 | "claim.name" : "locale",
1030 | "jsonType.label" : "String"
1031 | }
1032 | } ],
1033 | "useTemplateConfig" : false,
1034 | "useTemplateScope" : false,
1035 | "useTemplateMappers" : false
1036 | } ],
1037 | "clientTemplates" : [ ],
1038 | "browserSecurityHeaders" : {
1039 | "xContentTypeOptions" : "nosniff",
1040 | "xRobotsTag" : "none",
1041 | "xFrameOptions" : "SAMEORIGIN",
1042 | "xXSSProtection" : "1; mode=block",
1043 | "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
1044 | "strictTransportSecurity" : "max-age=31536000; includeSubDomains"
1045 | },
1046 | "smtpServer" : { },
1047 | "eventsEnabled" : false,
1048 | "eventsListeners" : [ "jboss-logging" ],
1049 | "enabledEventTypes" : [ ],
1050 | "adminEventsEnabled" : false,
1051 | "adminEventsDetailsEnabled" : false,
1052 | "components" : {
1053 | "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ {
1054 | "id" : "6908d5c3-07a7-4c00-91d7-462affb7425a",
1055 | "name" : "Consent Required",
1056 | "providerId" : "consent-required",
1057 | "subType" : "anonymous",
1058 | "subComponents" : { },
1059 | "config" : { }
1060 | }, {
1061 | "id" : "f2fbbda7-bc89-474c-80cd-c7817d27e852",
1062 | "name" : "Allowed Client Templates",
1063 | "providerId" : "allowed-client-templates",
1064 | "subType" : "anonymous",
1065 | "subComponents" : { },
1066 | "config" : { }
1067 | }, {
1068 | "id" : "e98e7d78-69d1-4f78-86a9-6aac95c7ce28",
1069 | "name" : "Trusted Hosts",
1070 | "providerId" : "trusted-hosts",
1071 | "subType" : "anonymous",
1072 | "subComponents" : { },
1073 | "config" : {
1074 | "host-sending-registration-request-must-match" : [ "true" ],
1075 | "client-uris-must-match" : [ "true" ]
1076 | }
1077 | }, {
1078 | "id" : "9643017a-e4a3-435e-9c92-a14298a5f7ed",
1079 | "name" : "Allowed Protocol Mapper Types",
1080 | "providerId" : "allowed-protocol-mappers",
1081 | "subType" : "anonymous",
1082 | "subComponents" : { },
1083 | "config" : {
1084 | "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" ],
1085 | "consent-required-for-all-mappers" : [ "true" ]
1086 | }
1087 | }, {
1088 | "id" : "a72ad67b-392d-462b-a24d-359584948a39",
1089 | "name" : "Max Clients Limit",
1090 | "providerId" : "max-clients",
1091 | "subType" : "anonymous",
1092 | "subComponents" : { },
1093 | "config" : {
1094 | "max-clients" : [ "200" ]
1095 | }
1096 | }, {
1097 | "id" : "39d518a7-6678-415f-aee0-497ddf0bbb8f",
1098 | "name" : "Allowed Protocol Mapper Types",
1099 | "providerId" : "allowed-protocol-mappers",
1100 | "subType" : "authenticated",
1101 | "subComponents" : { },
1102 | "config" : {
1103 | "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" ],
1104 | "consent-required-for-all-mappers" : [ "true" ]
1105 | }
1106 | }, {
1107 | "id" : "f690379c-6479-4533-ac55-660d4d519849",
1108 | "name" : "Full Scope Disabled",
1109 | "providerId" : "scope",
1110 | "subType" : "anonymous",
1111 | "subComponents" : { },
1112 | "config" : { }
1113 | }, {
1114 | "id" : "fda00934-5922-4028-9e7c-c123100c248f",
1115 | "name" : "Allowed Client Templates",
1116 | "providerId" : "allowed-client-templates",
1117 | "subType" : "authenticated",
1118 | "subComponents" : { },
1119 | "config" : { }
1120 | } ],
1121 | "org.keycloak.keys.KeyProvider" : [ {
1122 | "id" : "1cf453a3-7702-4d4d-8614-72c1fc6b17b6",
1123 | "name" : "hmac-generated",
1124 | "providerId" : "hmac-generated",
1125 | "subComponents" : { },
1126 | "config" : {
1127 | "kid" : [ "012044b2-dfa4-49cb-a4c5-916c19f9b96e" ],
1128 | "secret" : [ "nEC6RCMTKBsF49bfzb3Vv21Vh4TLEaFiRAfvQp2YOOE" ],
1129 | "priority" : [ "100" ]
1130 | }
1131 | }, {
1132 | "id" : "83881f72-2def-46a5-b8ba-99ad0b1e4c95",
1133 | "name" : "rsa-generated",
1134 | "providerId" : "rsa-generated",
1135 | "subComponents" : { },
1136 | "config" : {
1137 | "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" ],
1138 | "certificate" : [ "MIIClzCCAX8CBgFi1H8iNDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARkZW1vMB4XDTE4MDQxNzE2NDM0NFoXDTI4MDQxNzE2NDUyNFowDzENMAsGA1UEAwwEZGVtbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI3NOh8VEueAH5sYsNBlxHA/C0tOVFVOShdIXO+wj7k+ko/WrU3NXHEYp3NuELhNmHU7WBqRC7GBpMrpfua+vOPb2wrEHXK6tSaS4a3v63p241Fs/cAapaYSMD3AEe7EiSh54foOSvojkOwEGoiRqPrZWa1ynxEZ2oUzVVmmRwiDPvNqFL8hWl4VdF8ocUMvUbQ6uOxp1hIGfcQrwljw2SYxuhpv+qyH2aXaqjeYfBqrDqAlMZyyUtF2T//Brf6GRf2PMjCqzooLPN4ZtYq3jBWQ7BoKfs//PpvdgqWwEkmzuR126YTvS2UE2dARRxx+wwYxfUGXon0G1B9bchjMwy0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAavonr2grkWPCSLDRRCyTly2q/By5FYhkN5Bu7c2pxQy/k1OKJUBz+GIPxSL6MrPmHoWHM9fpD9nLCa1VHbHkEiu9p0c+2CDPVAyYvVbADVdgL+xp19TMyvETMfS1tJKVyJbqL8RsxzjWm1qI19VmVWNNHUGXpuPp35DL5tL/RkooY6+oNamsiNwR6xXmfqY7l6w8HA4y8It3yaeHy6N2ffjI/2AtXTyISuEEv1Lybr5op4jKRYLqv+ly7aBeNIGGnHFXlGyCqv8dSWSYXA1S83x4LeTHrj7rAC4fORY2Q5VNmhUAYYE5Vy+zxAHSoQn+cEf2qJsr9xRlYy8nzyXukw==" ],
1139 | "priority" : [ "100" ]
1140 | }
1141 | }, {
1142 | "id" : "46800710-eced-4804-a79e-32f7c5797b04",
1143 | "name" : "aes-generated",
1144 | "providerId" : "aes-generated",
1145 | "subComponents" : { },
1146 | "config" : {
1147 | "kid" : [ "2b922283-df55-4424-8bef-3f2ff5ba0bfa" ],
1148 | "secret" : [ "Ry49w356XdzGeEQbsupsvA" ],
1149 | "priority" : [ "100" ]
1150 | }
1151 | } ]
1152 | },
1153 | "internationalizationEnabled" : false,
1154 | "supportedLocales" : [ ],
1155 | "authenticationFlows" : [ {
1156 | "id" : "a48d9b79-b52f-4d29-b831-ecb9098352ad",
1157 | "alias" : "Handle Existing Account",
1158 | "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider",
1159 | "providerId" : "basic-flow",
1160 | "topLevel" : false,
1161 | "builtIn" : true,
1162 | "authenticationExecutions" : [ {
1163 | "authenticator" : "idp-confirm-link",
1164 | "requirement" : "REQUIRED",
1165 | "priority" : 10,
1166 | "userSetupAllowed" : false,
1167 | "autheticatorFlow" : false
1168 | }, {
1169 | "authenticator" : "idp-email-verification",
1170 | "requirement" : "ALTERNATIVE",
1171 | "priority" : 20,
1172 | "userSetupAllowed" : false,
1173 | "autheticatorFlow" : false
1174 | }, {
1175 | "requirement" : "ALTERNATIVE",
1176 | "priority" : 30,
1177 | "flowAlias" : "Verify Existing Account by Re-authentication",
1178 | "userSetupAllowed" : false,
1179 | "autheticatorFlow" : true
1180 | } ]
1181 | }, {
1182 | "id" : "03731267-4cd9-478d-ac04-403d1d832d46",
1183 | "alias" : "Verify Existing Account by Re-authentication",
1184 | "description" : "Reauthentication of existing account",
1185 | "providerId" : "basic-flow",
1186 | "topLevel" : false,
1187 | "builtIn" : true,
1188 | "authenticationExecutions" : [ {
1189 | "authenticator" : "idp-username-password-form",
1190 | "requirement" : "REQUIRED",
1191 | "priority" : 10,
1192 | "userSetupAllowed" : false,
1193 | "autheticatorFlow" : false
1194 | }, {
1195 | "authenticator" : "auth-otp-form",
1196 | "requirement" : "OPTIONAL",
1197 | "priority" : 20,
1198 | "userSetupAllowed" : false,
1199 | "autheticatorFlow" : false
1200 | } ]
1201 | }, {
1202 | "id" : "bb3fec2b-49dc-4ca3-bb31-8acb74b3e1bd",
1203 | "alias" : "browser",
1204 | "description" : "browser based authentication",
1205 | "providerId" : "basic-flow",
1206 | "topLevel" : true,
1207 | "builtIn" : true,
1208 | "authenticationExecutions" : [ {
1209 | "authenticator" : "auth-cookie",
1210 | "requirement" : "ALTERNATIVE",
1211 | "priority" : 10,
1212 | "userSetupAllowed" : false,
1213 | "autheticatorFlow" : false
1214 | }, {
1215 | "authenticator" : "auth-spnego",
1216 | "requirement" : "DISABLED",
1217 | "priority" : 20,
1218 | "userSetupAllowed" : false,
1219 | "autheticatorFlow" : false
1220 | }, {
1221 | "authenticator" : "identity-provider-redirector",
1222 | "requirement" : "ALTERNATIVE",
1223 | "priority" : 25,
1224 | "userSetupAllowed" : false,
1225 | "autheticatorFlow" : false
1226 | }, {
1227 | "requirement" : "ALTERNATIVE",
1228 | "priority" : 30,
1229 | "flowAlias" : "forms",
1230 | "userSetupAllowed" : false,
1231 | "autheticatorFlow" : true
1232 | } ]
1233 | }, {
1234 | "id" : "84567fef-a17f-424c-9f30-c5ae041beeee",
1235 | "alias" : "clients",
1236 | "description" : "Base authentication for clients",
1237 | "providerId" : "client-flow",
1238 | "topLevel" : true,
1239 | "builtIn" : true,
1240 | "authenticationExecutions" : [ {
1241 | "authenticator" : "client-secret",
1242 | "requirement" : "ALTERNATIVE",
1243 | "priority" : 10,
1244 | "userSetupAllowed" : false,
1245 | "autheticatorFlow" : false
1246 | }, {
1247 | "authenticator" : "client-jwt",
1248 | "requirement" : "ALTERNATIVE",
1249 | "priority" : 20,
1250 | "userSetupAllowed" : false,
1251 | "autheticatorFlow" : false
1252 | } ]
1253 | }, {
1254 | "id" : "731a2721-79ff-46ec-8dcb-ea7d19f86d33",
1255 | "alias" : "direct grant",
1256 | "description" : "OpenID Connect Resource Owner Grant",
1257 | "providerId" : "basic-flow",
1258 | "topLevel" : true,
1259 | "builtIn" : true,
1260 | "authenticationExecutions" : [ {
1261 | "authenticator" : "direct-grant-validate-username",
1262 | "requirement" : "REQUIRED",
1263 | "priority" : 10,
1264 | "userSetupAllowed" : false,
1265 | "autheticatorFlow" : false
1266 | }, {
1267 | "authenticator" : "direct-grant-validate-password",
1268 | "requirement" : "REQUIRED",
1269 | "priority" : 20,
1270 | "userSetupAllowed" : false,
1271 | "autheticatorFlow" : false
1272 | }, {
1273 | "authenticator" : "direct-grant-validate-otp",
1274 | "requirement" : "OPTIONAL",
1275 | "priority" : 30,
1276 | "userSetupAllowed" : false,
1277 | "autheticatorFlow" : false
1278 | } ]
1279 | }, {
1280 | "id" : "3c5c6d83-ccb5-420d-8370-253c43a6d598",
1281 | "alias" : "docker auth",
1282 | "description" : "Used by Docker clients to authenticate against the IDP",
1283 | "providerId" : "basic-flow",
1284 | "topLevel" : true,
1285 | "builtIn" : true,
1286 | "authenticationExecutions" : [ {
1287 | "authenticator" : "docker-http-basic-authenticator",
1288 | "requirement" : "REQUIRED",
1289 | "priority" : 10,
1290 | "userSetupAllowed" : false,
1291 | "autheticatorFlow" : false
1292 | } ]
1293 | }, {
1294 | "id" : "81f1a3b5-7737-4351-a4bd-25e98b536798",
1295 | "alias" : "first broker login",
1296 | "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account",
1297 | "providerId" : "basic-flow",
1298 | "topLevel" : true,
1299 | "builtIn" : true,
1300 | "authenticationExecutions" : [ {
1301 | "authenticatorConfig" : "review profile config",
1302 | "authenticator" : "idp-review-profile",
1303 | "requirement" : "REQUIRED",
1304 | "priority" : 10,
1305 | "userSetupAllowed" : false,
1306 | "autheticatorFlow" : false
1307 | }, {
1308 | "authenticatorConfig" : "create unique user config",
1309 | "authenticator" : "idp-create-user-if-unique",
1310 | "requirement" : "ALTERNATIVE",
1311 | "priority" : 20,
1312 | "userSetupAllowed" : false,
1313 | "autheticatorFlow" : false
1314 | }, {
1315 | "requirement" : "ALTERNATIVE",
1316 | "priority" : 30,
1317 | "flowAlias" : "Handle Existing Account",
1318 | "userSetupAllowed" : false,
1319 | "autheticatorFlow" : true
1320 | } ]
1321 | }, {
1322 | "id" : "46ba7967-ea06-45e3-98af-11200a34473e",
1323 | "alias" : "forms",
1324 | "description" : "Username, password, otp and other auth forms.",
1325 | "providerId" : "basic-flow",
1326 | "topLevel" : false,
1327 | "builtIn" : true,
1328 | "authenticationExecutions" : [ {
1329 | "authenticator" : "auth-username-password-form",
1330 | "requirement" : "REQUIRED",
1331 | "priority" : 10,
1332 | "userSetupAllowed" : false,
1333 | "autheticatorFlow" : false
1334 | }, {
1335 | "authenticator" : "auth-otp-form",
1336 | "requirement" : "OPTIONAL",
1337 | "priority" : 20,
1338 | "userSetupAllowed" : false,
1339 | "autheticatorFlow" : false
1340 | } ]
1341 | }, {
1342 | "id" : "4f2620ae-bb89-4d85-b81e-6e5d20c78a47",
1343 | "alias" : "registration",
1344 | "description" : "registration flow",
1345 | "providerId" : "basic-flow",
1346 | "topLevel" : true,
1347 | "builtIn" : true,
1348 | "authenticationExecutions" : [ {
1349 | "authenticator" : "registration-page-form",
1350 | "requirement" : "REQUIRED",
1351 | "priority" : 10,
1352 | "flowAlias" : "registration form",
1353 | "userSetupAllowed" : false,
1354 | "autheticatorFlow" : true
1355 | } ]
1356 | }, {
1357 | "id" : "7fb032fb-dac9-4ea8-9d63-678753437440",
1358 | "alias" : "registration form",
1359 | "description" : "registration form",
1360 | "providerId" : "form-flow",
1361 | "topLevel" : false,
1362 | "builtIn" : true,
1363 | "authenticationExecutions" : [ {
1364 | "authenticator" : "registration-user-creation",
1365 | "requirement" : "REQUIRED",
1366 | "priority" : 20,
1367 | "userSetupAllowed" : false,
1368 | "autheticatorFlow" : false
1369 | }, {
1370 | "authenticator" : "registration-profile-action",
1371 | "requirement" : "REQUIRED",
1372 | "priority" : 40,
1373 | "userSetupAllowed" : false,
1374 | "autheticatorFlow" : false
1375 | }, {
1376 | "authenticator" : "registration-password-action",
1377 | "requirement" : "REQUIRED",
1378 | "priority" : 50,
1379 | "userSetupAllowed" : false,
1380 | "autheticatorFlow" : false
1381 | }, {
1382 | "authenticator" : "registration-recaptcha-action",
1383 | "requirement" : "DISABLED",
1384 | "priority" : 60,
1385 | "userSetupAllowed" : false,
1386 | "autheticatorFlow" : false
1387 | } ]
1388 | }, {
1389 | "id" : "75600e80-cae6-4347-a506-ddf6477cd7e9",
1390 | "alias" : "reset credentials",
1391 | "description" : "Reset credentials for a user if they forgot their password or something",
1392 | "providerId" : "basic-flow",
1393 | "topLevel" : true,
1394 | "builtIn" : true,
1395 | "authenticationExecutions" : [ {
1396 | "authenticator" : "reset-credentials-choose-user",
1397 | "requirement" : "REQUIRED",
1398 | "priority" : 10,
1399 | "userSetupAllowed" : false,
1400 | "autheticatorFlow" : false
1401 | }, {
1402 | "authenticator" : "reset-credential-email",
1403 | "requirement" : "REQUIRED",
1404 | "priority" : 20,
1405 | "userSetupAllowed" : false,
1406 | "autheticatorFlow" : false
1407 | }, {
1408 | "authenticator" : "reset-password",
1409 | "requirement" : "REQUIRED",
1410 | "priority" : 30,
1411 | "userSetupAllowed" : false,
1412 | "autheticatorFlow" : false
1413 | }, {
1414 | "authenticator" : "reset-otp",
1415 | "requirement" : "OPTIONAL",
1416 | "priority" : 40,
1417 | "userSetupAllowed" : false,
1418 | "autheticatorFlow" : false
1419 | } ]
1420 | }, {
1421 | "id" : "4990dbc0-bb0b-48b5-8f72-945adcf77d39",
1422 | "alias" : "saml ecp",
1423 | "description" : "SAML ECP Profile Authentication Flow",
1424 | "providerId" : "basic-flow",
1425 | "topLevel" : true,
1426 | "builtIn" : true,
1427 | "authenticationExecutions" : [ {
1428 | "authenticator" : "http-basic-authenticator",
1429 | "requirement" : "REQUIRED",
1430 | "priority" : 10,
1431 | "userSetupAllowed" : false,
1432 | "autheticatorFlow" : false
1433 | } ]
1434 | } ],
1435 | "authenticatorConfig" : [ {
1436 | "id" : "da120730-f96f-4a0b-9f97-48d63823b067",
1437 | "alias" : "create unique user config",
1438 | "config" : {
1439 | "require.password.update.after.registration" : "false"
1440 | }
1441 | }, {
1442 | "id" : "0c76ade9-f703-4606-bae9-28f0bf131e11",
1443 | "alias" : "review profile config",
1444 | "config" : {
1445 | "update.profile.on.first.login" : "missing"
1446 | }
1447 | } ],
1448 | "requiredActions" : [ {
1449 | "alias" : "CONFIGURE_TOTP",
1450 | "name" : "Configure OTP",
1451 | "providerId" : "CONFIGURE_TOTP",
1452 | "enabled" : true,
1453 | "defaultAction" : false,
1454 | "config" : { }
1455 | }, {
1456 | "alias" : "UPDATE_PASSWORD",
1457 | "name" : "Update Password",
1458 | "providerId" : "UPDATE_PASSWORD",
1459 | "enabled" : true,
1460 | "defaultAction" : false,
1461 | "config" : { }
1462 | }, {
1463 | "alias" : "UPDATE_PROFILE",
1464 | "name" : "Update Profile",
1465 | "providerId" : "UPDATE_PROFILE",
1466 | "enabled" : true,
1467 | "defaultAction" : false,
1468 | "config" : { }
1469 | }, {
1470 | "alias" : "VERIFY_EMAIL",
1471 | "name" : "Verify Email",
1472 | "providerId" : "VERIFY_EMAIL",
1473 | "enabled" : true,
1474 | "defaultAction" : false,
1475 | "config" : { }
1476 | }, {
1477 | "alias" : "terms_and_conditions",
1478 | "name" : "Terms and Conditions",
1479 | "providerId" : "terms_and_conditions",
1480 | "enabled" : false,
1481 | "defaultAction" : false,
1482 | "config" : { }
1483 | } ],
1484 | "browserFlow" : "browser",
1485 | "registrationFlow" : "registration",
1486 | "directGrantFlow" : "direct grant",
1487 | "resetCredentialsFlow" : "reset credentials",
1488 | "clientAuthenticationFlow" : "clients",
1489 | "dockerAuthenticationFlow" : "docker auth",
1490 | "attributes" : {
1491 | "_browser_header.xXSSProtection" : "1; mode=block",
1492 | "_browser_header.xFrameOptions" : "SAMEORIGIN",
1493 | "_browser_header.strictTransportSecurity" : "max-age=31536000; includeSubDomains",
1494 | "permanentLockout" : "false",
1495 | "quickLoginCheckMilliSeconds" : "1000",
1496 | "_browser_header.xRobotsTag" : "none",
1497 | "maxFailureWaitSeconds" : "900",
1498 | "minimumQuickLoginWaitSeconds" : "60",
1499 | "failureFactor" : "30",
1500 | "actionTokenGeneratedByUserLifespan" : "300",
1501 | "maxDeltaTimeSeconds" : "43200",
1502 | "_browser_header.xContentTypeOptions" : "nosniff",
1503 | "actionTokenGeneratedByAdminLifespan" : "43200",
1504 | "bruteForceProtected" : "false",
1505 | "_browser_header.contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
1506 | "waitIncrementSeconds" : "60"
1507 | },
1508 | "keycloakVersion" : "3.4.3.Final"
1509 | }
--------------------------------------------------------------------------------