Skip to content
Open

PR #2

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

FROM openjdk:17-jdk-slim
VOLUME /tmp
COPY target/spring-keycloak-demo-1.0.0.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
ENTRYPOINT ["java", "-jar", "/app.jar"]
12 changes: 8 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
version: '3.8'

services:
keycloak:
image: keycloak/keycloak:21.1.0
image: keycloak/keycloak:latest
container_name: keycloak
volumes:
- ./keycloak/providers:/opt/keycloak/providers
- ./keycloak/logs:/opt/keycloak/logs
environment:
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
- QUARKUS_LOG_FILE_ENABLED="true"
- QUARKUS_LOG_FILE_PATH=/opt/keycloak/logs/spi.log
- QUARKUS_LOG_FILE_LEVEL=INFO
command: start-dev
ports:
- "8080:8080"

spring-app:
build: .
container_name: spring-keycloak-demo
Expand All @@ -19,4 +23,4 @@ services:
environment:
SPRING_PROFILES_ACTIVE: dev
depends_on:
- keycloak
- keycloak
Binary file not shown.
7 changes: 7 additions & 0 deletions keycloak/themes/mytheme/login/cli_splash.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
_ __ _ _
| |/ /___ _ _ ___| | ___ __ _| | __
| ' // _ \ | | |/ __| |/ _ \ / _` | |/ /
| . \ __/ |_| | (__| | (_) | (_| | <
|_|\_\___|\__, |\___|_|\___/ \__,_|_|\_\
|___/

19 changes: 19 additions & 0 deletions keycloak/themes/mytheme/login/code.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<#if section = "header">
<#if code.success>
${msg("codeSuccessTitle")}
<#else>
${kcSanitize(msg("codeErrorTitle", code.error))}
</#if>
<#elseif section = "form">
<div id="kc-code">
<#if code.success>
<p>${msg("copyCodeInstruction")}</p>
<input id="code" class="${properties.kcTextareaClass!}" value="${code.code}"/>
<#else>
<p id="error">${kcSanitize(code.error)}</p>
</#if>
</div>
</#if>
</@layout.registrationLayout>
33 changes: 33 additions & 0 deletions keycloak/themes/mytheme/login/delete-account-confirm.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>

<#if section = "header">
${msg("deleteAccountConfirm")}

<#elseif section = "form">

<form action="${url.loginAction}" class="form-vertical" method="post">

<div class="alert alert-warning" style="margin-top:0 !important;margin-bottom:30px !important">
<span class="pficon pficon-warning-triangle-o"></span>
${msg("irreversibleAction")}
</div>

<p>${msg("deletingImplies")}</p>
<ul style="color: #72767b;list-style: disc;list-style-position: inside;">
<li>${msg("loggingOutImmediately")}</li>
<li>${msg("errasingData")}</li>
</ul>

<p class="delete-account-text">${msg("finalDeletionConfirmation")}</p>

<div id="kc-form-buttons">
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doConfirmDelete")}" />
<#if triggered_from_aia>
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" style="margin-left: calc(100% - 220px)" type="submit" name="cancel-aia" value="true" />${msg("doCancel")}</button>
</#if>
</div>
</form>
</#if>

</@layout.registrationLayout>
15 changes: 15 additions & 0 deletions keycloak/themes/mytheme/login/delete-credential.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout displayMessage=false; section>
<#if section = "header">
${msg("deleteCredentialTitle", credentialLabel)}
<#elseif section = "form">
<div id="kc-delete-text">
${msg("deleteCredentialMessage", credentialLabel)}
</div>
<form class="form-actions" action="${url.loginAction}" method="POST">
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="accept" id="kc-accept" type="submit" value="${msg("doConfirmDelete")}"/>
<input class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="cancel-aia" value="${msg("doCancel")}" id="kc-decline" type="submit" />
</form>
<div class="clearfix"></div>
</#if>
</@layout.registrationLayout>
16 changes: 16 additions & 0 deletions keycloak/themes/mytheme/login/error.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout displayMessage=false; section>
<#if section = "header">
${kcSanitize(msg("errorTitle"))?no_esc}
<#elseif section = "form">
<div id="kc-error-message">
<p class="instruction">${kcSanitize(message.summary)?no_esc}</p>
<#if skipLink??>
<#else>
<#if client?? && client.baseUrl?has_content>
<p><a id="backToApplication" href="${client.baseUrl}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
</#if>
</#if>
</div>
</#if>
</@layout.registrationLayout>
3 changes: 3 additions & 0 deletions keycloak/themes/mytheme/login/footer.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<#macro content>
<#-- The footer at the bottom of the "login-box". You can override this file in your custom theme to declare a custom login footer element -->
</#macro>
30 changes: 30 additions & 0 deletions keycloak/themes/mytheme/login/frontchannel-logout.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<#if section = "header">
<script>
document.title = "${msg("frontchannel-logout.title")}";
</script>
${msg("frontchannel-logout.title")}
<#elseif section = "form">
<p>${msg("frontchannel-logout.message")}</p>
<ul>
<#list logout.clients as client>
<li>
${client.name}
<iframe src="${client.frontChannelLogoutUrl}" style="display:none;"></iframe>
</li>
</#list>
</ul>
<#if logout.logoutRedirectUri?has_content>
<script>
function readystatechange(event) {
if (document.readyState=='complete') {
window.location.replace('${logout.logoutRedirectUri}');
}
}
document.addEventListener('readystatechange', readystatechange);
</script>
<a id="continue" class="btn btn-primary" href="${logout.logoutRedirectUri}">${msg("doContinue")}</a>
</#if>
</#if>
</@layout.registrationLayout>
23 changes: 23 additions & 0 deletions keycloak/themes/mytheme/login/idp-review-user-profile.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<#import "template.ftl" as layout>
<#import "user-profile-commons.ftl" as userProfileCommons>
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
<#if section = "header">
${msg("loginIdpReviewProfileTitle")}
<#elseif section = "form">
<form id="kc-idp-review-profile-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">

<@userProfileCommons.userProfileFormFields/>

<div class="${properties.kcFormGroupClass!}">
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
<div class="${properties.kcFormOptionsWrapperClass!}">
</div>
</div>

<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
</div>
</div>
</form>
</#if>
</@layout.registrationLayout>
24 changes: 24 additions & 0 deletions keycloak/themes/mytheme/login/info.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout displayMessage=false; section>
<#if section = "header">
<#if messageHeader??>
${kcSanitize(msg("${messageHeader}"))?no_esc}
<#else>
${message.summary}
</#if>
<#elseif section = "form">
<div id="kc-info-message">
<p class="instruction">${message.summary}<#if requiredActions??><#list requiredActions>: <b><#items as reqActionItem>${kcSanitize(msg("requiredAction.${reqActionItem}"))?no_esc}<#sep>, </#items></b></#list><#else></#if></p>
<#if skipLink??>
<#else>
<#if pageRedirectUri?has_content>
<p><a href="${pageRedirectUri}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
<#elseif actionUri?has_content>
<p><a href="${actionUri}">${kcSanitize(msg("proceedWithAction"))?no_esc}</a></p>
<#elseif (client.baseUrl)?has_content>
<p><a href="${client.baseUrl}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
</#if>
</#if>
</div>
</#if>
</@layout.registrationLayout>
15 changes: 15 additions & 0 deletions keycloak/themes/mytheme/login/link-idp-action.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout displayMessage=false; section>
<#if section = "header">
${msg("linkIdpActionTitle", idpDisplayName)}
<#elseif section = "form">
<div id="kc-link-text">
${msg("linkIdpActionMessage", idpDisplayName)}
</div>
<form class="form-actions" action="${url.loginAction}" method="POST">
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="continue" id="kc-continue" type="submit" value="${msg("doContinue")}"/>
<input class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="cancel-aia" value="${msg("doCancel")}" id="kc-cancel" type="submit" />
</form>
<div class="clearfix"></div>
</#if>
</@layout.registrationLayout>
114 changes: 114 additions & 0 deletions keycloak/themes/mytheme/login/login-config-totp.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<#import "template.ftl" as layout>
<#import "password-commons.ftl" as passwordCommons>
<@layout.registrationLayout displayRequiredFields=false displayMessage=!messagesPerField.existsError('totp','userLabel'); section>

<#if section = "header">
${msg("loginTotpTitle")}
<#elseif section = "form">
<ol id="kc-totp-settings">
<li>
<p>${msg("loginTotpStep1")}</p>

<ul id="kc-totp-supported-apps">
<#list totp.supportedApplications as app>
<li>${msg(app)}</li>
</#list>
</ul>
</li>

<#if mode?? && mode = "manual">
<li>
<p>${msg("loginTotpManualStep2")}</p>
<p><span id="kc-totp-secret-key">${totp.totpSecretEncoded}</span></p>
<p><a href="${totp.qrUrl}" id="mode-barcode">${msg("loginTotpScanBarcode")}</a></p>
</li>
<li>
<p>${msg("loginTotpManualStep3")}</p>
<p>
<ul>
<li id="kc-totp-type">${msg("loginTotpType")}: ${msg("loginTotp." + totp.policy.type)}</li>
<li id="kc-totp-algorithm">${msg("loginTotpAlgorithm")}: ${totp.policy.getAlgorithmKey()}</li>
<li id="kc-totp-digits">${msg("loginTotpDigits")}: ${totp.policy.digits}</li>
<#if totp.policy.type = "totp">
<li id="kc-totp-period">${msg("loginTotpInterval")}: ${totp.policy.period}</li>
<#elseif totp.policy.type = "hotp">
<li id="kc-totp-counter">${msg("loginTotpCounter")}: ${totp.policy.initialCounter}</li>
</#if>
</ul>
</p>
</li>
<#else>
<li>
<p>${msg("loginTotpStep2")}</p>
<img id="kc-totp-secret-qr-code" src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"><br/>
<p><a href="${totp.manualUrl}" id="mode-manual">${msg("loginTotpUnableToScan")}</a></p>
</li>
</#if>
<li>
<p>${msg("loginTotpStep3")}</p>
<p>${msg("loginTotpStep3DeviceName")}</p>
</li>
</ol>

<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-totp-settings-form" method="post">
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcInputWrapperClass!}">
<label for="totp" class="control-label">${msg("authenticatorCode")}</label> <span class="required">*</span>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="totp" name="totp" autocomplete="off" class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('totp')>true</#if>"
dir="ltr"
/>

<#if messagesPerField.existsError('totp')>
<span id="input-error-otp-code" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('totp'))?no_esc}
</span>
</#if>

</div>
<input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}" />
<#if mode??><input type="hidden" id="mode" name="mode" value="${mode}"/></#if>
</div>

<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcInputWrapperClass!}">
<label for="userLabel" class="control-label">${msg("loginTotpDeviceName")}</label> <#if totp.otpCredentials?size gte 1><span class="required">*</span></#if>
</div>

<div class="${properties.kcInputWrapperClass!}">
<input type="text" class="${properties.kcInputClass!}" id="userLabel" name="userLabel" autocomplete="off"
aria-invalid="<#if messagesPerField.existsError('userLabel')>true</#if>" dir="ltr"
/>

<#if messagesPerField.existsError('userLabel')>
<span id="input-error-otp-label" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('userLabel'))?no_esc}
</span>
</#if>
</div>
</div>

<div class="${properties.kcFormGroupClass!}">
<@passwordCommons.logoutOtherSessions/>
</div>

<#if isAppInitiatedAction??>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
<button type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!} ${properties.kcButtonLargeClass!}"
id="cancelTOTPBtn" name="cancel-aia" value="true" />${msg("doCancel")}
</button>
<#else>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
</#if>
</form>
</#if>
</@layout.registrationLayout>
12 changes: 12 additions & 0 deletions keycloak/themes/mytheme/login/login-idp-link-confirm-override.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<#if section = "header">
${msg("confirmOverrideIdpTitle")}
<#elseif section = "form">
<form id="kc-register-form" action="${url.loginAction}" method="post">
${msg("pageExpiredMsg1")} <a id="loginRestartLink" href="${url.loginRestartFlowUrl}">${msg("doClickHere")}</a>

<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="submitAction" id="confirmOverride" value="confirmOverride">${msg("confirmOverrideIdpContinue", idpDisplayName)}</button>
</form>
</#if>
</@layout.registrationLayout>
13 changes: 13 additions & 0 deletions keycloak/themes/mytheme/login/login-idp-link-confirm.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<#if section = "header">
${msg("confirmLinkIdpTitle")}
<#elseif section = "form">
<form id="kc-register-form" action="${url.loginAction}" method="post">
<div class="${properties.kcFormGroupClass!}">
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="submitAction" id="updateProfile" value="updateProfile">${msg("confirmLinkIdpReviewProfile")}</button>
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="submitAction" id="linkAccount" value="linkAccount">${msg("confirmLinkIdpContinue", idpDisplayName)}</button>
</div>
</form>
</#if>
</@layout.registrationLayout>
16 changes: 16 additions & 0 deletions keycloak/themes/mytheme/login/login-idp-link-email.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<#if section = "header">
${msg("emailLinkIdpTitle", idpDisplayName)}
<#elseif section = "form">
<p id="instruction1" class="instruction">
${msg("emailLinkIdp1", idpDisplayName, brokerContext.username, realm.displayName)}
</p>
<p id="instruction2" class="instruction">
${msg("emailLinkIdp2")} <a href="${url.loginAction}">${msg("doClickHere")}</a> ${msg("emailLinkIdp3")}
</p>
<p id="instruction3" class="instruction">
${msg("emailLinkIdp4")} <a href="${url.loginAction}">${msg("doClickHere")}</a> ${msg("emailLinkIdp5")}
</p>
</#if>
</@layout.registrationLayout>
Loading