├── .dockerignore ├── .gitignore ├── .maven-dockerignore ├── LICENSE.txt ├── README.md ├── keycloak-assembly ├── .maven-dockerignore ├── pom.xml └── src │ └── main │ ├── docker │ ├── .maven-dockerignore │ └── Dockerfile │ └── realm-config │ └── quickstart-realm.json ├── keycloak-identity-providers ├── keycloak-identity-provider-authenticator │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── keycloak │ │ │ └── examples │ │ │ └── authenticator │ │ │ ├── SecretQuestionAuthenticator.java │ │ │ ├── SecretQuestionAuthenticatorFactory.java │ │ │ ├── SecretQuestionCredentialProvider.java │ │ │ ├── SecretQuestionCredentialProviderFactory.java │ │ │ ├── SecretQuestionRequiredAction.java │ │ │ └── SecretQuestionRequiredActionFactory.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ ├── org.keycloak.authentication.AuthenticatorFactory │ │ ├── org.keycloak.authentication.RequiredActionFactory │ │ └── org.keycloak.credential.CredentialProviderFactory └── pom.xml ├── keycloak-integration-tests └── pom.xml ├── keycloak-theme ├── pom.xml └── src │ ├── assembly │ └── theme.xml │ └── main │ └── resources │ ├── META-INF │ └── keycloak-themes.json │ └── theme │ ├── address │ ├── account │ │ ├── account.ftl │ │ └── theme.properties │ ├── admin │ │ ├── resources │ │ │ └── partials │ │ │ │ └── user-attributes.html │ │ └── theme.properties │ └── login │ │ ├── login-update-profile.ftl │ │ ├── register.ftl │ │ └── theme.properties │ ├── authenticator-example │ └── login │ │ ├── secret-question-config.ftl │ │ └── secret-question.ftl │ ├── logo-example │ ├── account │ │ ├── resources │ │ │ ├── css │ │ │ │ └── logo.css │ │ │ └── img │ │ │ │ └── red-hat-logo.png │ │ └── theme.properties │ ├── admin │ │ ├── resources │ │ │ ├── css │ │ │ │ └── logo.css │ │ │ └── img │ │ │ │ └── red-hat-logo.png │ │ └── theme.properties │ ├── login │ │ ├── resources │ │ │ ├── css │ │ │ │ └── logo.css │ │ │ └── img │ │ │ │ └── red-hat-logo.png │ │ └── theme.properties │ └── welcome │ │ ├── index.ftl │ │ ├── resources │ │ └── red-hat-logo.png │ │ └── theme.properties │ └── sunrise │ └── login │ ├── resources │ ├── css │ │ └── styles.css │ └── img │ │ └── bkgrnd.jpg │ └── theme.properties └── pom.xml /.dockerignore: -------------------------------------------------------------------------------- 1 | target/** 2 | .maven-dockerignore 3 | 4 | ###################### 5 | # Mac OSX 6 | ###################### 7 | .DS_Store 8 | .svn 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear on external disk 14 | .Spotlight-V100 15 | .Trashes 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ###################### 2 | # Project Specific 3 | ###################### 4 | /src/test/javascript/coverage/ 5 | 6 | ###################### 7 | # Node 8 | ###################### 9 | /node/ 10 | node_tmp/ 11 | npm-debug.log.* 12 | 13 | ###################### 14 | # SASS 15 | ###################### 16 | .sass-cache/ 17 | 18 | ###################### 19 | # Eclipse 20 | ###################### 21 | *.pydevproject 22 | .project 23 | .metadata 24 | tmp/ 25 | tmp/**/* 26 | *.tmp 27 | *.bak 28 | *.swp 29 | *~.nib 30 | local.properties 31 | .classpath 32 | .settings/ 33 | .loadpath 34 | .factorypath 35 | /src/main/resources/rebel.xml 36 | 37 | # External tool builders 38 | .externalToolBuilders/** 39 | 40 | # Locally stored "Eclipse launch configurations" 41 | *.launch 42 | 43 | # CDT-specific 44 | .cproject 45 | 46 | # PDT-specific 47 | .buildpath 48 | 49 | ###################### 50 | # Intellij 51 | ###################### 52 | .idea/ 53 | *.iml 54 | *.iws 55 | *.ipr 56 | *.ids 57 | *.orig 58 | classes/ 59 | 60 | ###################### 61 | # Visual Studio Code 62 | ###################### 63 | .vscode/ 64 | 65 | ###################### 66 | # Maven 67 | ###################### 68 | /log/ 69 | target 70 | 71 | ###################### 72 | # Gradle 73 | ###################### 74 | .gradle/ 75 | /build/ 76 | 77 | ###################### 78 | # Package Files 79 | ###################### 80 | #*.jar 81 | *.war 82 | *.ear 83 | *.db 84 | 85 | ###################### 86 | # Windows 87 | ###################### 88 | # Windows image file caches 89 | Thumbs.db 90 | 91 | # Folder config file 92 | Desktop.ini 93 | 94 | ###################### 95 | # Mac OSX 96 | ###################### 97 | .DS_Store 98 | .svn 99 | 100 | # Thumbnails 101 | ._* 102 | 103 | # Files that might appear on external disk 104 | .Spotlight-V100 105 | .Trashes 106 | 107 | ###################### 108 | # Directories 109 | ###################### 110 | /bin/ 111 | /deploy/ 112 | 113 | ###################### 114 | # Logs 115 | ###################### 116 | *.log* 117 | 118 | ###################### 119 | # Others 120 | ###################### 121 | *.class 122 | *.*~ 123 | *~ 124 | .merge_file* 125 | 126 | ###################### 127 | # Gradle Wrapper 128 | ###################### 129 | !gradle/wrapper/gradle-wrapper.jar 130 | 131 | ###################### 132 | # Maven Wrapper 133 | ###################### 134 | !.mvn/wrapper/maven-wrapper.jar 135 | 136 | ###################### 137 | # ESLint 138 | ###################### 139 | .eslintcache 140 | -------------------------------------------------------------------------------- /.maven-dockerignore: -------------------------------------------------------------------------------- 1 | target/** -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Keycloak Docker Quickstart 2 | This project is aimed to manage Keycloak extensions using a fully Maven lifecycle. 3 | The current supported component are the following: 4 | 5 | * keycloak-assembly 6 | * keycloak-identity-providers 7 | * keycloak-integration-tests 8 | * keycloak-theme 9 | 10 | Developed and tested on Keycloak 20.0.1. 11 | 12 | ## Requirements 13 | In order to use this project, you need to install the following components: 14 | 15 | * Apache Maven 3.8.x 16 | * Docker 17 | 18 | 19 | ## Keycloak Assembly 20 | This is the Maven assembly module for deploying the platform in any environment that is not currently supporting Docker. 21 | The final artifact for this module is a folder tree as the following: 22 | 23 | * realm-config 24 | * themes 25 | 26 | ## Keycloak Identity Providers 27 | Main module that includes all the needed custom providers and authenticators. 28 | The default project contains only a single custom authenticator but you can easily add new providers following the same configuration approach. 29 | 30 | **Custom Authenticator** 31 | This is the implementation of the secret question provider taken from the Keycloak examples folder. 32 | 33 | ## Keycloak Integration Tests 34 | This module will install and run all the artifacts using Docker. 35 | It can include also your own code for integration tests after executing your custom image. 36 | 37 | **Building** 38 | ``` 39 | mvn clean package 40 | ``` 41 | 42 | This will also regenerate the Dockerfile in the project root. 43 | 44 | **Running Integration Tests** 45 | 46 | To execute integration tests you can run the following command: 47 | 48 | ``` 49 | mvn clean integration-test 50 | ``` 51 | 52 | A specific Maven property (docker.keepRunning) is provided to decide if keep running the container after the execution of tests or not. 53 | Please consider that the default value is true, this means that you have to manually stop the container after executing integration-test. 54 | 55 | 56 | ## Saving and running the Custom Keycloak Docker image 57 | In order to execute the build process locally of the Docker image **custom/keycloak:latest** 58 | ``` 59 | mvn clean package 60 | mvn install 61 | ``` 62 | 63 | After the startup of Keycloak, you can access as admin/admin from the admin console URL: 64 | ``` 65 | http://localhost:8080 66 | ``` 67 | 68 | A quickstart realm is provided to test your extensions. 69 | 70 | To dynamically regenerate the Dockerfile and build only the Docker image: 71 | ``` 72 | mvn clean package 73 | docker build -t custom/keycloak:${project.version} . 74 | ``` 75 | 76 | Run the latest Docker image: 77 | 78 | ``` 79 | docker run -p 8080:8080 -p 9090:9090 custom/keycloak:${project.version} 80 | ``` 81 | 82 | ## Keycloak Themes 83 | This module includes the default example of themes with the addition of the secret question sample templates taken from the default authenticator. 84 | 85 | ## Deliverables 86 | 87 | **Overlays** 88 | 89 | | Source | Target deployment | Artifact | 90 | | -------- | -------- | -------- | 91 | | /src/main/realm-config | /opt/keycloak/data/import | Folder | 92 | | /keycloak-theme/target/keycloak-theme-${project.version}.jar | /opt/keycloak/themes | JAR | 93 | | /keycloak-identity-providers/keycloak-identity-provider-authenticator/target/keycloak-identity-provider-authenticator-${project.version}.jar | /opt/keycloak/providers | JAR | 94 | 95 | **Docker image** 96 | The Docker image is written inside your local repo but it is also available in the following path: 97 | 98 | ``` 99 | /target/docker/custom/keycloak/${project.version}/tmp/docker-build.tar.gz 100 | ``` 101 | -------------------------------------------------------------------------------- /keycloak-assembly/.maven-dockerignore: -------------------------------------------------------------------------------- 1 | target/** -------------------------------------------------------------------------------- /keycloak-assembly/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | keycloak-docker-quickstart 5 | org.keycloak 6 | 1.0.0-SNAPSHOT 7 | 8 | 4.0.0 9 | keycloak-assembly 10 | Keycloak - Docker 11 | pom 12 | 13 | 14 | 15 | 16 | org.apache.maven.plugins 17 | maven-resources-plugin 18 | 19 | 20 | false 21 | filter-dockerfiles 22 | process-resources 23 | 24 | copy-resources 25 | 26 | 27 | true 28 | 29 | 30 | 31 | ${project.basedir}/src/main/docker 32 | true 33 | 34 | Dockerfile 35 | 36 | 37 | 38 | ${project.basedir}/src/main 39 | false 40 | 41 | realm-config/** 42 | 43 | 44 | 45 | 46 | ${project.parent.basedir}/keycloak-theme/target 47 | false 48 | 49 | *${project.version}.jar 50 | 51 | 52 | 53 | ${project.parent.basedir}/keycloak-identity-providers/keycloak-identity-provider-authenticator/target 54 | false 55 | 56 | *${project.version}.jar 57 | 58 | 59 | 60 | ${project.build.directory}/dockertmp 61 | 62 | 63 | 64 | 65 | 66 | io.fabric8 67 | docker-maven-plugin 68 | 69 | false 70 | ${docker.keycloak.showLogs} 71 | ${docker.keycloak.logAll} 72 | ${docker.keycloak.verbose} 73 | ${docker.keycloak.skipSave} 74 | 75 | 76 | custom-keycloak 77 | ${docker.keycloak.saveName} 78 | 79 | ${project.build.directory}/dockertmp 80 | gzip 81 | 82 | 83 | 84 | 85 | 86 | 87 | false 88 | save 89 | install 90 | 91 | build 92 | save 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /keycloak-assembly/src/main/docker/.maven-dockerignore: -------------------------------------------------------------------------------- 1 | target/** -------------------------------------------------------------------------------- /keycloak-assembly/src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ${docker.keycloak.groupId}/${docker.keycloak.image.name}:${keycloak.version} 2 | 3 | ENV KEYCLOAK_ADMIN ${docker.keycloak.user} 4 | ENV KEYCLOAK_ADMIN_PASSWORD ${docker.keycloak.password} 5 | ENV JAVA_OPTS -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -agentlib:jdwp=transport=dt_socket,address=0.0.0.0:${docker.keycloak.port.debug.internal},server=y,suspend=n 6 | 7 | COPY ${docker.keycloak.volume.internal.realm-config} ${docker.keycloak.volume.external.realm-config} 8 | COPY ${docker.keycloak.volume.internal.providers.authenticator.1} ${docker.keycloak.volume.external.providers.authenticator.1} 9 | COPY ${docker.keycloak.volume.internal.theme} ${docker.keycloak.volume.external.theme} 10 | 11 | EXPOSE ${docker.keycloak.port.internal} 12 | EXPOSE ${docker.keycloak.port.debug.internal} 13 | 14 | CMD ["${docker.keycloak.run.cmd.arg.1}", "${docker.keycloak.run.cmd.arg.2}"] 15 | -------------------------------------------------------------------------------- /keycloak-assembly/src/main/realm-config/quickstart-realm.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm": "quickstart", 3 | "enabled": true, 4 | "accessTokenLifespan": 60, 5 | "accessCodeLifespan": 60, 6 | "accessCodeLifespanUserAction": 300, 7 | "ssoSessionIdleTimeout": 600, 8 | "ssoSessionMaxLifespan": 36000, 9 | "sslRequired": "external", 10 | "registrationAllowed": false, 11 | "privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=", 12 | "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", 13 | "requiredCredentials": [ "password" ], 14 | "users" : [ 15 | { 16 | "username" : "alice", 17 | "enabled": true, 18 | "email" : "alice@keycloak.org", 19 | "firstName": "Alice", 20 | "lastName": "Liddel", 21 | "credentials" : [ 22 | { "type" : "password", 23 | "value" : "password" } 24 | ], 25 | "realmRoles": [ "user", "offline_access" ], 26 | "clientRoles": { 27 | "account": [ "manage-account" ] 28 | } 29 | }, 30 | { 31 | "username" : "test-admin", 32 | "enabled": true, 33 | "email" : "test@admin.org", 34 | "firstName": "Admin", 35 | "lastName": "Test", 36 | "credentials" : [ 37 | { "type" : "password", 38 | "value" : "password" } 39 | ], 40 | "realmRoles": [ "user","admin" ], 41 | "clientRoles": { 42 | "realm-management": [ "realm-admin" ], 43 | "account": [ "manage-account" ] 44 | } 45 | } 46 | ], 47 | "roles" : { 48 | "realm" : [ 49 | { 50 | "name": "user", 51 | "description": "User privileges" 52 | }, 53 | { 54 | "name": "admin", 55 | "description": "Administrator privileges" 56 | } 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | org.keycloak 6 | keycloak-identity-providers 7 | 1.0.0-SNAPSHOT 8 | 9 | 4.0.0 10 | Keycloak - Identity Provider - Authenticator 11 | 12 | keycloak-identity-provider-authenticator 13 | jar 14 | 15 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.keycloak.examples.authenticator; 19 | 20 | import static org.keycloak.common.util.ServerCookie.SameSiteAttributeValue.NONE; 21 | 22 | import java.net.URI; 23 | 24 | import javax.ws.rs.core.Cookie; 25 | import javax.ws.rs.core.HttpHeaders; 26 | import javax.ws.rs.core.MultivaluedMap; 27 | import javax.ws.rs.core.Response; 28 | 29 | import org.jboss.resteasy.spi.HttpResponse; 30 | import org.jboss.resteasy.spi.ResteasyProviderFactory; 31 | import org.keycloak.authentication.AuthenticationFlowContext; 32 | import org.keycloak.authentication.AuthenticationFlowError; 33 | import org.keycloak.authentication.Authenticator; 34 | import org.keycloak.common.util.ServerCookie; 35 | import org.keycloak.models.AuthenticatorConfigModel; 36 | import org.keycloak.models.KeycloakSession; 37 | import org.keycloak.models.RealmModel; 38 | import org.keycloak.models.UserCredentialModel; 39 | import org.keycloak.models.UserModel; 40 | 41 | /** 42 | * @author Bill Burke 43 | * @version $Revision: 1 $ 44 | */ 45 | public class SecretQuestionAuthenticator implements Authenticator { 46 | 47 | public static final String CREDENTIAL_TYPE = "secret_question"; 48 | 49 | protected boolean hasCookie(AuthenticationFlowContext context) { 50 | Cookie cookie = context.getHttpRequest().getHttpHeaders().getCookies().get("SECRET_QUESTION_ANSWERED"); 51 | boolean result = cookie != null; 52 | if (result) { 53 | System.out.println("Bypassing secret question because cookie is set"); 54 | } 55 | return result; 56 | } 57 | 58 | @Override 59 | public void authenticate(AuthenticationFlowContext context) { 60 | if (hasCookie(context)) { 61 | context.success(); 62 | return; 63 | } 64 | Response challenge = context.form().createForm("secret-question.ftl"); 65 | context.challenge(challenge); 66 | } 67 | 68 | @Override 69 | public void action(AuthenticationFlowContext context) { 70 | MultivaluedMap formData = context.getHttpRequest().getDecodedFormParameters(); 71 | if (formData.containsKey("cancel")) { 72 | context.cancelLogin(); 73 | return; 74 | } 75 | boolean validated = validateAnswer(context); 76 | if (!validated) { 77 | Response challenge = context.form().setError("badSecret").createForm("secret-question.ftl"); 78 | context.failureChallenge(AuthenticationFlowError.INVALID_CREDENTIALS, challenge); 79 | return; 80 | } 81 | setCookie(context); 82 | context.success(); 83 | } 84 | 85 | protected void setCookie(AuthenticationFlowContext context) { 86 | AuthenticatorConfigModel config = context.getAuthenticatorConfig(); 87 | int maxCookieAge = 60 * 60 * 24 * 30; // 30 days 88 | if (config != null) { 89 | maxCookieAge = Integer.valueOf(config.getConfig().get("cookie.max.age")); 90 | 91 | } 92 | URI uri = context.getUriInfo().getBaseUriBuilder().path("realms").path(context.getRealm().getName()).build(); 93 | addCookie("SECRET_QUESTION_ANSWERED", "true", uri.getRawPath(), null, null, maxCookieAge, false, true); 94 | } 95 | 96 | public static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, 97 | boolean secure, boolean httpOnly) { 98 | HttpResponse response = ResteasyProviderFactory.peekInstance().getContextData(HttpResponse.class); 99 | StringBuffer cookieBuf = new StringBuffer(); 100 | ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, comment, maxAge, secure, httpOnly, 101 | NONE); 102 | String cookie = cookieBuf.toString(); 103 | response.getOutputHeaders().add(HttpHeaders.SET_COOKIE, cookie); 104 | } 105 | 106 | protected boolean validateAnswer(AuthenticationFlowContext context) { 107 | MultivaluedMap formData = context.getHttpRequest().getDecodedFormParameters(); 108 | String secret = formData.getFirst("secret_answer"); 109 | UserCredentialModel input = new UserCredentialModel("", SecretQuestionCredentialProvider.SECRET_QUESTION, 110 | secret); 111 | return context.getUser().credentialManager().isValid(input); 112 | } 113 | 114 | @Override 115 | public boolean requiresUser() { 116 | return true; 117 | } 118 | 119 | @Override 120 | public boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user) { 121 | return user.credentialManager().isConfiguredFor(SecretQuestionCredentialProvider.SECRET_QUESTION); 122 | } 123 | 124 | @Override 125 | public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) { 126 | user.addRequiredAction(SecretQuestionRequiredAction.PROVIDER_ID); 127 | } 128 | 129 | @Override 130 | public void close() { 131 | 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionAuthenticatorFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.keycloak.examples.authenticator; 19 | 20 | import org.keycloak.Config; 21 | import org.keycloak.authentication.Authenticator; 22 | import org.keycloak.authentication.AuthenticatorFactory; 23 | import org.keycloak.authentication.ConfigurableAuthenticatorFactory; 24 | import org.keycloak.models.AuthenticationExecutionModel; 25 | import org.keycloak.models.KeycloakSession; 26 | import org.keycloak.models.KeycloakSessionFactory; 27 | import org.keycloak.provider.ProviderConfigProperty; 28 | 29 | import java.util.ArrayList; 30 | import java.util.List; 31 | 32 | /** 33 | * @author Bill Burke 34 | * @version $Revision: 1 $ 35 | */ 36 | public class SecretQuestionAuthenticatorFactory implements AuthenticatorFactory, ConfigurableAuthenticatorFactory { 37 | 38 | public static final String PROVIDER_ID = "secret-question-authenticator"; 39 | private static final SecretQuestionAuthenticator SINGLETON = new SecretQuestionAuthenticator(); 40 | 41 | @Override 42 | public String getId() { 43 | return PROVIDER_ID; 44 | } 45 | 46 | @Override 47 | public Authenticator create(KeycloakSession session) { 48 | return SINGLETON; 49 | } 50 | 51 | private static AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = { 52 | AuthenticationExecutionModel.Requirement.REQUIRED, 53 | AuthenticationExecutionModel.Requirement.DISABLED 54 | }; 55 | @Override 56 | public AuthenticationExecutionModel.Requirement[] getRequirementChoices() { 57 | return REQUIREMENT_CHOICES; 58 | } 59 | 60 | @Override 61 | public boolean isUserSetupAllowed() { 62 | return true; 63 | } 64 | 65 | @Override 66 | public boolean isConfigurable() { 67 | return true; 68 | } 69 | 70 | @Override 71 | public List getConfigProperties() { 72 | return configProperties; 73 | } 74 | 75 | private static final List configProperties = new ArrayList(); 76 | 77 | static { 78 | ProviderConfigProperty property; 79 | property = new ProviderConfigProperty(); 80 | property.setName("cookie.max.age"); 81 | property.setLabel("Cookie Max Age"); 82 | property.setType(ProviderConfigProperty.STRING_TYPE); 83 | property.setHelpText("Max age in seconds of the SECRET_QUESTION_COOKIE."); 84 | configProperties.add(property); 85 | } 86 | 87 | 88 | @Override 89 | public String getHelpText() { 90 | return "A secret question that a user has to answer. i.e. What is your mother's maiden name."; 91 | } 92 | 93 | @Override 94 | public String getDisplayType() { 95 | return "Secret Question"; 96 | } 97 | 98 | @Override 99 | public String getReferenceCategory() { 100 | return "Secret Question"; 101 | } 102 | 103 | @Override 104 | public void init(Config.Scope config) { 105 | 106 | } 107 | 108 | @Override 109 | public void postInit(KeycloakSessionFactory factory) { 110 | 111 | } 112 | 113 | @Override 114 | public void close() { 115 | 116 | } 117 | 118 | 119 | } 120 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.keycloak.examples.authenticator; 18 | 19 | import java.util.Collections; 20 | import java.util.HashSet; 21 | import java.util.List; 22 | import java.util.Set; 23 | import java.util.stream.Collectors; 24 | import java.util.stream.Stream; 25 | 26 | import org.keycloak.common.util.Time; 27 | import org.keycloak.credential.CredentialInput; 28 | import org.keycloak.credential.CredentialInputUpdater; 29 | import org.keycloak.credential.CredentialInputValidator; 30 | import org.keycloak.credential.CredentialModel; 31 | import org.keycloak.credential.CredentialProvider; 32 | import org.keycloak.credential.CredentialTypeMetadata; 33 | import org.keycloak.credential.CredentialTypeMetadataContext; 34 | import org.keycloak.models.KeycloakSession; 35 | import org.keycloak.models.RealmModel; 36 | import org.keycloak.models.UserCredentialModel; 37 | import org.keycloak.models.UserModel; 38 | 39 | /** 40 | * @author Bill Burke 41 | * @version $Revision: 1 $ 42 | */ 43 | public class SecretQuestionCredentialProvider 44 | implements CredentialProvider, CredentialInputValidator, CredentialInputUpdater { 45 | public static final String SECRET_QUESTION = "SECRET_QUESTION"; 46 | public static final String CACHE_KEY = SecretQuestionCredentialProvider.class.getName() + "." + SECRET_QUESTION; 47 | 48 | protected KeycloakSession session; 49 | 50 | public SecretQuestionCredentialProvider(KeycloakSession session) { 51 | this.session = session; 52 | } 53 | 54 | public CredentialModel getSecret(RealmModel realm, UserModel user) { 55 | CredentialModel secret = null; 56 | List creds = user.credentialManager().getStoredCredentialsByTypeStream(SECRET_QUESTION) 57 | .collect(Collectors.toList()); 58 | if (!creds.isEmpty()) 59 | secret = creds.get(0); 60 | return secret; 61 | } 62 | 63 | @Override 64 | public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) { 65 | if (!SECRET_QUESTION.equals(input.getType())) 66 | return false; 67 | if (!(input instanceof UserCredentialModel)) 68 | return false; 69 | UserCredentialModel credInput = (UserCredentialModel) input; 70 | List creds = user.credentialManager().getStoredCredentialsByTypeStream(SECRET_QUESTION) 71 | .collect(Collectors.toList()); 72 | if (creds.isEmpty()) { 73 | CredentialModel secret = new CredentialModel(); 74 | secret.setType(SECRET_QUESTION); 75 | secret.setSecretData(credInput.getChallengeResponse()); 76 | secret.setCreatedDate(Time.currentTimeMillis()); 77 | user.credentialManager().createStoredCredential(secret); 78 | } else { 79 | creds.get(0).setCredentialData(credInput.getChallengeResponse()); 80 | user.credentialManager().createStoredCredential(creds.get(0)); 81 | } 82 | return true; 83 | } 84 | 85 | @Override 86 | public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) { 87 | if (!SECRET_QUESTION.equals(credentialType)) 88 | return; 89 | user.credentialManager().disableCredentialType(credentialType); 90 | 91 | } 92 | 93 | @Override 94 | @SuppressWarnings("unchecked") 95 | public Stream getDisableableCredentialTypesStream(RealmModel realm, UserModel user) { 96 | if (!user.credentialManager().getStoredCredentialsByTypeStream(SECRET_QUESTION).collect(Collectors.toList()) 97 | .isEmpty()) { 98 | Set set = new HashSet<>(); 99 | set.add(SECRET_QUESTION); 100 | return set.stream(); 101 | } else { 102 | return Collections.EMPTY_SET.stream(); 103 | } 104 | 105 | } 106 | 107 | @Override 108 | public boolean supportsCredentialType(String credentialType) { 109 | return SECRET_QUESTION.equals(credentialType); 110 | } 111 | 112 | @Override 113 | public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) { 114 | if (!SECRET_QUESTION.equals(credentialType)) 115 | return false; 116 | return getSecret(realm, user) != null; 117 | } 118 | 119 | @Override 120 | public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) { 121 | if (!SECRET_QUESTION.equals(input.getType())) 122 | return false; 123 | if (!(input instanceof UserCredentialModel)) 124 | return false; 125 | 126 | String secret = getSecret(realm, user).getSecretData(); 127 | 128 | return secret != null && ((UserCredentialModel) input).getChallengeResponse().equals(secret); 129 | } 130 | 131 | @Override 132 | public String getType() { 133 | return SECRET_QUESTION; 134 | } 135 | 136 | @Override 137 | public CredentialModel createCredential(RealmModel realm, UserModel user, CredentialModel credentialModel) { 138 | // TODO Auto-generated method stub 139 | return null; 140 | } 141 | 142 | @Override 143 | public boolean deleteCredential(RealmModel realm, UserModel user, String credentialId) { 144 | return false; 145 | } 146 | 147 | @Override 148 | public CredentialModel getCredentialFromModel(CredentialModel model) { 149 | return model; 150 | } 151 | 152 | @Override 153 | public CredentialTypeMetadata getCredentialTypeMetadata(CredentialTypeMetadataContext metadataContext) { 154 | // TODO Auto-generated method stub 155 | return null; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionCredentialProviderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.keycloak.examples.authenticator; 18 | 19 | import org.keycloak.credential.CredentialModel; 20 | import org.keycloak.credential.CredentialProvider; 21 | import org.keycloak.credential.CredentialProviderFactory; 22 | import org.keycloak.models.KeycloakSession; 23 | 24 | /** 25 | * @author Bill Burke 26 | * @version $Revision: 1 $ 27 | */ 28 | public class SecretQuestionCredentialProviderFactory 29 | implements CredentialProviderFactory { 30 | @Override 31 | public String getId() { 32 | return "secret-question"; 33 | } 34 | 35 | @Override 36 | public CredentialProvider create(KeycloakSession session) { 37 | return new SecretQuestionCredentialProvider(session); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.keycloak.examples.authenticator; 19 | 20 | import javax.ws.rs.core.Response; 21 | 22 | import org.keycloak.authentication.RequiredActionContext; 23 | import org.keycloak.authentication.RequiredActionProvider; 24 | import org.keycloak.models.UserCredentialModel; 25 | 26 | /** 27 | * @author Bill Burke 28 | * @version $Revision: 1 $ 29 | */ 30 | public class SecretQuestionRequiredAction implements RequiredActionProvider { 31 | public static final String PROVIDER_ID = "secret_question_config"; 32 | 33 | @Override 34 | public void evaluateTriggers(RequiredActionContext context) { 35 | 36 | } 37 | 38 | @Override 39 | public void requiredActionChallenge(RequiredActionContext context) { 40 | Response challenge = context.form().createForm("secret-question-config.ftl"); 41 | context.challenge(challenge); 42 | 43 | } 44 | 45 | @Override 46 | public void processAction(RequiredActionContext context) { 47 | String answer = (context.getHttpRequest().getDecodedFormParameters().getFirst("secret_answer")); 48 | UserCredentialModel input = new UserCredentialModel("", SecretQuestionCredentialProvider.SECRET_QUESTION, 49 | answer); 50 | context.getUser().credentialManager().updateCredential(input); 51 | context.success(); 52 | } 53 | 54 | @Override 55 | public void close() { 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/java/org/keycloak/examples/authenticator/SecretQuestionRequiredActionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package org.keycloak.examples.authenticator; 19 | 20 | import org.keycloak.Config; 21 | import org.keycloak.authentication.RequiredActionFactory; 22 | import org.keycloak.authentication.RequiredActionProvider; 23 | import org.keycloak.models.KeycloakSession; 24 | import org.keycloak.models.KeycloakSessionFactory; 25 | 26 | /** 27 | * @author Bill Burke 28 | * @version $Revision: 1 $ 29 | */ 30 | public class SecretQuestionRequiredActionFactory implements RequiredActionFactory { 31 | 32 | private static final SecretQuestionRequiredAction SINGLETON = new SecretQuestionRequiredAction(); 33 | 34 | @Override 35 | public RequiredActionProvider create(KeycloakSession session) { 36 | return SINGLETON; 37 | } 38 | 39 | 40 | @Override 41 | public String getId() { 42 | return SecretQuestionRequiredAction.PROVIDER_ID; 43 | } 44 | 45 | @Override 46 | public String getDisplayText() { 47 | return "Secret Question"; 48 | } 49 | 50 | @Override 51 | public void init(Config.Scope config) { 52 | 53 | } 54 | 55 | @Override 56 | public void postInit(KeycloakSessionFactory factory) { 57 | 58 | } 59 | 60 | @Override 61 | public void close() { 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.AuthenticatorFactory: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | org.keycloak.examples.authenticator.SecretQuestionAuthenticatorFactory -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | org.keycloak.examples.authenticator.SecretQuestionRequiredActionFactory -------------------------------------------------------------------------------- /keycloak-identity-providers/keycloak-identity-provider-authenticator/src/main/resources/META-INF/services/org.keycloak.credential.CredentialProviderFactory: -------------------------------------------------------------------------------- 1 | org.keycloak.examples.authenticator.SecretQuestionCredentialProviderFactory -------------------------------------------------------------------------------- /keycloak-identity-providers/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | org.keycloak 5 | keycloak-docker-quickstart 6 | 1.0.0-SNAPSHOT 7 | 8 | 9 | 4.0.0 10 | Keycloak - Identity Providers 11 | 12 | keycloak-identity-providers 13 | 14 | pom 15 | 16 | 17 | 18 | org.keycloak 19 | keycloak-core 20 | ${keycloak.version} 21 | provided 22 | 23 | 24 | org.keycloak 25 | keycloak-server-spi 26 | ${keycloak.version} 27 | provided 28 | 29 | 30 | org.keycloak 31 | keycloak-server-spi-private 32 | ${keycloak.version} 33 | provided 34 | 35 | 36 | org.keycloak 37 | keycloak-services 38 | ${keycloak.version} 39 | provided 40 | 41 | 42 | 43 | 44 | 45 | 46 | io.fabric8 47 | docker-maven-plugin 48 | 49 | true 50 | 51 | 52 | 53 | 54 | 55 | 56 | keycloak-identity-provider-authenticator 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /keycloak-integration-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | keycloak-docker-quickstart 5 | org.keycloak 6 | 1.0.0-SNAPSHOT 7 | 8 | 9 | 4.0.0 10 | keycloak-integration-tests 11 | Keycloak - Integration Test Suite 12 | pom 13 | 14 | 15 | 16 | 17 | io.fabric8 18 | docker-maven-plugin 19 | 20 | ${docker.keepRunning} 21 | false 22 | ${docker.keycloak.showLogs} 23 | ${docker.keycloak.logAll} 24 | ${docker.keycloak.verbose} 25 | ${docker.keycloak.skipSave} 26 | 27 | 28 | ${docker.keycloak.groupId}/keycloak:${keycloak.version} 29 | 30 | 31 | ${docker.keycloak.port.external}:${docker.keycloak.port.internal} 32 | 33 | 34 | ${docker.keycloak.user} 35 | ${docker.keycloak.password} 36 | 37 | 38 | 39 | 40 | http://${docker.host.address}:${docker.keycloak.port.test} 41 | 42 | 43 | 44 | 45 | 46 | ${docker.keycloak.run.cmd.arg.1} 47 | ${docker.keycloak.run.cmd.arg.2} 48 | 49 | 50 | 51 | 52 | ${docker.keycloak.bind.volume.realm-config} 53 | ${docker.keycloak.bind.volume.theme} 54 | ${docker.keycloak.bind.volume.providers.authenticator.1} 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | start 64 | pre-integration-test 65 | 66 | start 67 | 68 | 69 | 70 | stop 71 | post-integration-test 72 | 73 | stop 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /keycloak-theme/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | keycloak-docker-quickstart 5 | org.keycloak 6 | 1.0.0-SNAPSHOT 7 | 8 | 9 | 4.0.0 10 | Keycloak - Theme 11 | 12 | keycloak-theme 13 | 14 | 15 | 16 | 17 | maven-assembly-plugin 18 | 19 | 20 | src/assembly/theme.xml 21 | 22 | 23 | 24 | 25 | create-archive-theme 26 | package 27 | 28 | single 29 | 30 | 31 | 32 | 33 | 34 | io.fabric8 35 | docker-maven-plugin 36 | 37 | true 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /keycloak-theme/src/assembly/theme.xml: -------------------------------------------------------------------------------- 1 | 4 | package 5 | 6 | zip 7 | 8 | 9 | 10 | ${project.basedir}/src/main/resources 11 | ${file.separator} 12 | 13 | 14 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/META-INF/keycloak-themes.json: -------------------------------------------------------------------------------- 1 | { 2 | "themes": [{ 3 | "name" : "address", 4 | "types": [ "admin", "account", "login" ] 5 | }, { 6 | "name" : "logo-example", 7 | "types": [ "admin", "account", "login", "welcome" ] 8 | }, { 9 | "name" : "sunrise", 10 | "types": [ "login" ] 11 | }, { 12 | "name" : "authenticator-example", 13 | "types": [ "login" ] 14 | }] 15 | } 16 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/address/account/account.ftl: -------------------------------------------------------------------------------- 1 | <#import "template.ftl" as layout> 2 | <@layout.mainLayout active='account' bodyClass='user'; section> 3 | 4 |
5 |
6 |

${msg("editAccountHtmlTitle")}

7 |
8 |
9 | * ${msg("requiredFields")} 10 |
11 |
12 | 13 |
14 | 15 | 16 | 17 |
18 |
19 | <#if realm.editUsernameAllowed>* 20 |
21 | 22 |
23 | disabled="disabled" value="${(account.username!'')}"/> 24 |
25 |
26 | 27 |
28 |
29 | * 30 |
31 | 32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 | * 40 |
41 | 42 |
43 | 44 |
45 |
46 | 47 |
48 |
49 | * 50 |
51 | 52 |
53 | 54 |
55 |
56 | 57 |
58 |
59 | 60 |
61 | 62 |
63 | 64 |
65 |
66 |
67 |
68 | 69 |
70 | 71 |
72 | 73 |
74 |
75 |
76 |
77 | 78 |
79 | 80 |
81 | 82 |
83 |
84 |
85 |
86 | 87 |
88 | 89 |
90 | 91 |
92 |
93 |
94 |
95 | 96 |
97 | 98 |
99 | 100 |
101 |
102 | 103 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/address/account/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=keycloak -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/address/admin/resources/partials/user-attributes.html: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 | 23 | 24 | 25 | 26 |
27 |
28 | 29 |
30 | 31 |
32 | Street address. 33 |
34 |
35 | 36 |
37 | 38 |
39 | City or locality. 40 |
41 |
42 | 43 |
44 | 45 |
46 | State, province, prefecture, or region. 47 |
48 |
49 | 50 |
51 | 52 |
53 | Zip code or postal code. 54 |
55 |
56 | 57 |
58 | 59 |
60 | Country name. 61 |
62 | 63 |
64 |
65 | 66 | 67 |
68 |
69 |
70 |
71 | 72 | 73 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/address/admin/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=keycloak -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/address/login/login-update-profile.ftl: -------------------------------------------------------------------------------- 1 | <#import "template.ftl" as layout> 2 | <@layout.registrationLayout; section> 3 | <#if section = "title"> 4 | ${msg("loginProfileTitle")} 5 | <#elseif section = "header"> 6 | ${msg("loginProfileTitle")} 7 | <#elseif section = "form"> 8 |
9 |
10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 | 18 |
19 |
20 | 21 |
22 |
23 | 24 |
25 |
26 | 27 |
28 |
29 | 30 |
31 |
32 | 33 |
34 |
35 | 36 |
37 |
38 | 39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 | 48 |
49 | 50 |
51 | 52 |
53 |
54 |
55 |
56 | 57 |
58 | 59 |
60 | 61 |
62 |
63 |
64 |
65 | 66 |
67 | 68 |
69 | 70 |
71 |
72 |
73 |
74 | 75 |
76 | 77 |
78 | 79 |
80 |
81 | 82 | 83 |
84 |
85 |
86 |
87 |
88 | 89 |
90 | 91 |
92 |
93 |
94 | 95 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/address/login/register.ftl: -------------------------------------------------------------------------------- 1 | <#import "template.ftl" as layout> 2 | <@layout.registrationLayout; section> 3 | <#if section = "title"> 4 | ${msg("registerWithTitle",(realm.name!''))} 5 | <#elseif section = "header"> 6 | ${msg("registerWithTitleHtml",(realm.name!''))} 7 | <#elseif section = "form"> 8 |
9 | <#if !realm.registrationEmailAsUsername> 10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 | 40 |
41 |
42 | 43 |
44 |
45 | 46 | <#if passwordRequired> 47 |
48 |
49 | 50 |
51 |
52 | 53 |
54 |
55 | 56 |
57 |
58 | 59 |
60 |
61 | 62 |
63 |
64 | 65 |
66 |
67 | 68 |
69 | 70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 | 79 |
80 | 81 |
82 |
83 |
84 |
85 | 86 |
87 | 88 |
89 | 90 |
91 |
92 |
93 |
94 | 95 |
96 | 97 |
98 | 99 |
100 |
101 |
102 |
103 | 104 |
105 | 106 |
107 | 108 |
109 |
110 | <#if recaptchaRequired??> 111 |
112 |
113 |
114 |
115 |
116 | 117 | 118 |
119 |
120 | 123 |
124 | 125 |
126 | 127 |
128 |
129 |
130 | 131 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/address/login/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=keycloak -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/authenticator-example/login/secret-question-config.ftl: -------------------------------------------------------------------------------- 1 | <#import "template.ftl" as layout> 2 | <@layout.registrationLayout; section> 3 | <#if section = "title"> 4 | ${msg("loginTitle",realm.name)} 5 | <#elseif section = "header"> 6 | Setup Secret Question 7 | <#elseif section = "form"> 8 |
9 |
10 |
11 | 12 |
13 | 14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/authenticator-example/login/secret-question.ftl: -------------------------------------------------------------------------------- 1 | <#import "template.ftl" as layout> 2 | <@layout.registrationLayout; section> 3 | <#if section = "title"> 4 | ${msg("loginTitle",realm.name)} 5 | <#elseif section = "header"> 6 | ${msg("loginTitleHtml",realm.name)} 7 | <#elseif section = "form"> 8 |
9 |
10 |
11 | 12 |
13 | 14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 |
23 |
24 | 25 |
26 |
27 | 28 | 29 |
30 |
31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/account/resources/css/logo.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | .navbar-title { 19 | background: url('../img/red-hat-logo.png') no-repeat; 20 | height: 45px; 21 | width: 150px; 22 | } -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/account/resources/img/red-hat-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPj/keycloak-docker-quickstart/c5eeb8cd0afba49bed0f8a5931a61a9dfa7c8b6c/keycloak-theme/src/main/resources/theme/logo-example/account/resources/img/red-hat-logo.png -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/account/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=keycloak 19 | import=common/keycloak 20 | 21 | styles=lib/patternfly/css/patternfly.css css/account.css css/logo.css -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/admin/resources/css/logo.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | .navbar-pf .navbar-brand { 20 | background: url('../img/red-hat-logo.png') no-repeat 0px 5px; 21 | } -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/admin/resources/img/red-hat-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPj/keycloak-docker-quickstart/c5eeb8cd0afba49bed0f8a5931a61a9dfa7c8b6c/keycloak-theme/src/main/resources/theme/logo-example/admin/resources/img/red-hat-logo.png -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/admin/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=keycloak 19 | import=common/keycloak 20 | styles=lib/patternfly/css/patternfly.css node_modules/select2/select2.css css/styles.css css/logo.css -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/login/resources/css/logo.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #kc-logo-wrapper { 19 | background: url("../img/red-hat-logo.png") no-repeat top right; 20 | height: 45px; 21 | width: 200px; 22 | } 23 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/login/resources/img/red-hat-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPj/keycloak-docker-quickstart/c5eeb8cd0afba49bed0f8a5931a61a9dfa7c8b6c/keycloak-theme/src/main/resources/theme/logo-example/login/resources/img/red-hat-logo.png -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/login/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=keycloak 19 | import=common/keycloak 20 | 21 | styles=lib/patternfly/css/patternfly.css node_modules/patternfly/dist/css/patternfly-additions.css lib/zocial/zocial.css css/login.css css/logo.css -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/welcome/index.ftl: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | Welcome to Keycloak 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 | 32 |

Welcome to Keycloak

33 | 34 |

Your Keycloak is running.

35 | 36 |

Documentation | Administration Console

37 | 38 |

Keycloak Project | 39 | Mailing List | 40 | Report an issue

41 |

JBoss and JBoss Community

42 |
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/welcome/resources/red-hat-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPj/keycloak-docker-quickstart/c5eeb8cd0afba49bed0f8a5931a61a9dfa7c8b6c/keycloak-theme/src/main/resources/theme/logo-example/welcome/resources/red-hat-logo.png -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/logo-example/welcome/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=keycloak -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/sunrise/login/resources/css/styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | * and other contributors as indicated by the @author tags. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | @import url('../../keycloak/lib/zocial/zocial.css'); 19 | 20 | body { 21 | background-color: #040507; 22 | background-image: url('../img/bkgrnd.jpg'); 23 | background-size: cover; 24 | background-repeat: no-repeat; 25 | 26 | color: #fff; 27 | font-family: sans-serif; 28 | text-shadow: 0px 0px 10px #000; 29 | } 30 | 31 | a { 32 | color: #fff; 33 | } 34 | 35 | div#kc-content { 36 | position: absolute; 37 | top: 20%; 38 | left: 50%; 39 | width: 550px; 40 | margin-left: -225px; 41 | } 42 | 43 | div#kc-form { 44 | float: left; 45 | width: 350px; 46 | } 47 | 48 | div#kc-form label { 49 | display: block; 50 | font-size: 16px; 51 | } 52 | 53 | div#info-area { 54 | position: fixed; 55 | bottom: 0; 56 | left: 0; 57 | margin-top: 40px; 58 | background-color: rgba(0, 0, 0, 0.4); 59 | padding: 20px; 60 | width: 100%; 61 | } 62 | 63 | div#info-area p { 64 | margin-right: 30px; 65 | display: inline; 66 | text-shadow: none; 67 | } 68 | 69 | input[type=text], input[type=password] { 70 | color: #ddd; 71 | font-size: 18px; 72 | margin-bottom: 20px; 73 | background-color: rgba(3,70,114,0.15); 74 | border: 0px solid rgba(0,0,0,0.2); 75 | box-shadow:inset 0 0 2px 2px rgba(0,0,0,0.15); 76 | padding: 10px; 77 | width: 296px; 78 | } 79 | 80 | input[type=text]:hover, input[type=password]:hover { 81 | background-color: rgba(3,70,114,0.4); 82 | } 83 | 84 | input[type=submit] { 85 | border: none; 86 | 87 | background: -webkit-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)); 88 | background: -moz-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)); 89 | background: -ms-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)); 90 | background: -o-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)); 91 | 92 | box-shadow: 0px 0px 6px rgba(0,0,0,0.5); 93 | 94 | color: rgba(0,0,0,0.6); 95 | 96 | font-size: 14px; 97 | font-weight: bold; 98 | 99 | padding: 10px; 100 | margin-top: 20px; 101 | margin-right: 10px; 102 | width: 150px; 103 | } 104 | 105 | input[type=submit]:hover { 106 | background-color: rgba(255,255,255,0.8); 107 | } 108 | 109 | div#kc-form-options div { 110 | display: inline-block; 111 | margin-right: 20px; 112 | font-size: 12px; 113 | } 114 | 115 | div#kc-form-options div label { 116 | font-size: 12px; 117 | } 118 | 119 | div#kc-feedback { 120 | box-shadow: 0px 0px 6px rgba(0,0,0,0.5); 121 | position: fixed; 122 | top: 0; 123 | left: 0; 124 | width: 100%; 125 | text-align: center; 126 | } 127 | 128 | div#kc-feedback-wrapper { 129 | padding: 1em; 130 | } 131 | 132 | div.feedback-success { 133 | background-color: rgba(155,155,255,0.1); 134 | } 135 | 136 | div.feedback-warning { 137 | background-color: rgba(255,175,0,0.1); 138 | } 139 | 140 | div.feedback-error { 141 | background-color: rgba(255,0,0,0.1); 142 | } 143 | 144 | div#kc-header { 145 | display: none; 146 | } 147 | 148 | div#kc-registration { 149 | margin-bottom: 20px; 150 | } 151 | 152 | div#social-login { 153 | border-left: 1px solid rgba(255, 255, 255, 0.2); 154 | float: right; 155 | width: 150px; 156 | padding: 20px 0 200px 40px; 157 | } 158 | 159 | div.social-login span { 160 | display: none; 161 | } 162 | 163 | div#kc-social-providers ul { 164 | list-style: none; 165 | margin: 0; 166 | padding: 0; 167 | } 168 | 169 | div#kc-social-providers ul li { 170 | margin-bottom: 20px; 171 | } 172 | 173 | div#kc-social-providers ul li span { 174 | display: inline; 175 | width: 100px; 176 | } 177 | 178 | a.zocial { 179 | border: none; 180 | background: -webkit-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)) !important; 181 | background: -moz-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)) !important; 182 | background: -ms-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)) !important; 183 | background: -o-linear-gradient(top, rgba(255,255,255,0.8), rgba(255,255,255,0.1)) !important; 184 | box-shadow: 0px 0px 6px rgba(0,0,0,0.5); 185 | color: rgba(0,0,0,0.6); 186 | width: 130px; 187 | text-shadow: none; 188 | -webkit-border-radius: 0; 189 | -moz-border-radius: 0; 190 | border-radius: 0; 191 | padding-top: 0.2em; 192 | padding-bottom: 0.2em; 193 | } 194 | -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/sunrise/login/resources/img/bkgrnd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenPj/keycloak-docker-quickstart/c5eeb8cd0afba49bed0f8a5931a61a9dfa7c8b6c/keycloak-theme/src/main/resources/theme/sunrise/login/resources/img/bkgrnd.jpg -------------------------------------------------------------------------------- /keycloak-theme/src/main/resources/theme/sunrise/login/theme.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Red Hat, Inc. and/or its affiliates 3 | # and other contributors as indicated by the @author tags. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | parent=base 19 | styles=css/styles.css -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | org.keycloak 5 | keycloak-docker-quickstart 6 | 1.0.0-SNAPSHOT 7 | Keycloak - SDK Docker Quickstart 8 | pom 9 | 10 | 11 | UTF-8 12 | UTF-8 13 | 14 | 11 15 | 11 16 | 17 | 18 | 20.0.2 19 | 20 | 21 | true 22 | quay.io/keycloak 23 | keycloak 24 | keycloak 25 | admin 26 | admin 27 | 8080 28 | 8080 29 | 8080 30 | 9090 31 | 9090 32 | 120000 33 | 34 | 35 | true 36 | true 37 | true 38 | 39 | 40 | start-dev 41 | --import-realm 42 | 43 | 44 | 45 | 46 | 47 | /realm-config 48 | /opt/keycloak/data/import 49 | 50 | 51 | /keycloak-theme-${project.version}.jar 52 | /opt/keycloak/providers/keycloak-theme-${project.version}.jar 53 | 54 | 55 | /keycloak-identity-provider-authenticator-${project.version}.jar 56 | /opt/keycloak/providers/keycloak-identity-provider-authenticator-${project.version}.jar 57 | 58 | 59 | ../keycloak-assembly/src/main${docker.keycloak.volume.internal.realm-config}:${docker.keycloak.volume.external.realm-config} 60 | ../keycloak-theme/target${docker.keycloak.volume.internal.theme}:${docker.keycloak.volume.external.theme} 61 | ../keycloak-identity-providers/keycloak-identity-provider-authenticator/target${docker.keycloak.volume.internal.providers.authenticator.1}:${docker.keycloak.volume.external.providers.authenticator.1} 62 | 63 | 64 | custom/keycloak:${project.version} 65 | custom-keycloak-server 66 | false 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.apache.maven.plugins 75 | maven-resources-plugin 76 | 3.3.0 77 | 78 | 79 | io.fabric8 80 | docker-maven-plugin 81 | 0.40.2 82 | 83 | 84 | 85 | 86 | 87 | 88 | keycloak-theme 89 | keycloak-identity-providers 90 | keycloak-assembly 91 | keycloak-integration-tests 92 | 93 | 94 | 95 | --------------------------------------------------------------------------------