8000 Infinite recursion after upgrading to v26 · Issue #844 · keycloakify/keycloakify · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Infinite recursion after upgrading to v26 #844

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Dezash opened this issue May 7, 2025 · 9 comments
Open

Infinite recursion after upgrading to v26 #844

Dezash opened this issue May 7, 2025 · 9 comments

Comments

@Dezash
Copy link
Dezash commented May 7, 2025

Hi, after upgrading Keycloak to 26.2.1 login attempts result in infinite recursions.
I'm using an unmodified keycloakify-starter project v11.8.24 (keycloak-theme-for-kc-all-other-versions.jar) and Keycloak phasetwo build. The issue does not occur with default login themes such as base, keycloak, or keycloak.v2
The issue seems to be related to a custom browser authentication flow because it starts working if I disable it.
I cannot share the source code of the custom authenticator, but I can share the template that is generated in the processTemplate method of DefaultFreeMarkerProvider. I don't understand much about how FreeMarker works, but perhaps you could point me to what I should be looking for?

Generated template:
template.txt

Stacktrace:
stacktrace.txt

@garronej
Copy link
Collaborator
garronej commented May 7, 2025

Hello @Dezash,

Thank you for reporting.

Hello @xgp, did you experience that? I can fix quick if I can reproduce.

Best,

@xgp
Copy link
xgp commented May 7, 2025

I don't believe we've seen this issue. @pnzrr Can you please take a look when you have time?

@pnzrr
Copy link
Contributor
pnzrr commented May 7, 2025

@Dezash it's not something I've seen in our usage of Keycloakify.

I tested this with the 26.2.1 and 26.2.3 (our current release). KC project was v11.8.26

I had no issue setting the login theme to keycloakify-starter and doing a login.

Can you further show your config? Possibly a video? Make sure to try a login to the server as an admin in an incognito window to avoid session and cookie contamination.

@Dezash
Copy link
Author
Dezash commented May 8, 2025

After further investigation I've pinpointed the exact code that causes the issue and managed to make a minimal example that can reproduce the issue in a new realm. It seems that the issue occurs when setting the "hidpd" form parameter.

The only configuration is:
keycloak-starter set as the login theme
Browser authentication flow is bound to a flow that contains an enabled "Hidpd Bug Reproduce Authenticator" execution

 package org.myorg.Authenticators.idp;
 
 import org.keycloak.Config;
 import org.keycloak.authentication.Authenticator;
 import org.keycloak.authentication.AuthenticatorFactory;
 import org.keycloak.models.AuthenticationExecutionModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.provider.ProviderConfigProperty;
 import org.keycloak.provider.ProviderConfigurationBuilder;
 import org.keycloak.provider.ServerInfoAwareProviderFactory;
 
 import java.util.List;
 import java.util.Map;
 
 import static org.keycloak.models.AuthenticationExecutionModel.Requirement.*;
 
 public class HidpdBugAuthenticatorFactory implements AuthenticatorFactory, ServerInfoAwareProviderFactory {
     private static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = new AuthenticationExecutionModel.Requirement[]{REQUIRED, ALTERNATIVE, DISABLED};
 
     private static final String PROVIDER_ID = "hidpd-bug-reproduce-authenticator";
 
     private Config.Scope config;
 
     @Override
     public String getDisplayType() {
         return "Hidpd Bug Reproduce Authenticator";
     }
 
     @Override
     public String getReferenceCategory() {
         return "Authorization";
     }
 
     @Override
     public boolean isConfigurable() {
         return true;
     }
 
     @Override
     public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
         return REQUIREMENT_CHOICES;
     }
 
     @Override
     public boolean isUserSetupAllowed() {
         return false;
     }
 
     @Override
     public String getHelpText() {
         return "Reproduces Hidpd infinite recursion bug for Keycloakify. Enable this in your browser authentication flow and try logging in with Keycloakify set as the login theme.";
     }
 
     @Override
     public List<ProviderConfigProperty> getConfigProperties() {
         return ProviderConfigurationBuilder.create()
                 .build();
     }
 
     @Override
     public Authenticator create(KeycloakSession session) {
         return new HidpdBugAuthenticator();
     }
 
     @Override
     public void init(Config.Scope config) {
         this.config = config;
     }
 
     @Override
     public void postInit(KeycloakSessionFactory factory) {
     }
 
     @Override
     public void close() {
     }
 
     @Override
     public String getId() {
         return PROVIDER_ID;
     }
 
     @Override
     public Map<String, String> getOperationalInfo() {
         return null;
     }
 }
 package org.myorg.Authenticators.idp;
 
 import jakarta.ws.rs.core.Response;
 import org.keycloak.authentication.AuthenticationFlowContext;
 import org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator;
 import org.keycloak.forms.login.LoginFormsProvider;
 import org.keycloak.forms.login.freemarker.model.IdentityProviderBean;
 import org.keycloak.models.*;
 
 public class HidpdBugAuthenticator extends AbstractUsernameFormAuthenticator {
     @Override
     public void authenticate(AuthenticationFlowContext authenticationFlowContext) {
         LoginFormsProvider loginFormsProvider = authenticationFlowContext.form();
         Response challengeResponse = loginFormsProvider.createLoginUsername();
         authenticationFlowContext.challenge(challengeResponse);
     }
 
     @Override
     public void action(AuthenticationFlowContext authenticationFlowContext) {
         var hidpd = new IdentityProviderBean(
                 authenticationFlowContext.getSession(),
                 authenticationFlowContext.getRealm(),
                 null,
                 authenticationFlowContext);
 
         var loginFormsProvider = authenticationFlowContext.form();
         loginFormsProvider.setAttribute("hidpd", hidpd);
 
         authenticationFlowContext.attempted
8000
();
     }
 
     @Override
     protected Response createLoginForm(LoginFormsProvider form) {
         return form.createLoginUsername();
     }
 
     @Override
     protected String getDefaultChallengeMessage(AuthenticationFlowContext context) {
         return "";
     }
 
     @Override
     public boolean requiresUser() {
         return false;
     }
 
     @Override
     public boolean configuredFor(KeycloakSession keycloakSession, RealmModel realmModel, UserModel userModel) {
         return true;
     }
 
     @Override
     public void setRequiredActions(KeycloakSession keycloakSession, RealmModel realmModel, UserModel userModel) {
     }
 }

Realm for testing:
realm-export (4).json

Steps to reprpduce:

  1. Create a provider with the code above
  2. Start keycloak
  3. Import the realm
  4. Go to /realms/HidpdBugRealm/account
  5. Enter any existing username
  6. Observe the page being stuck on loading and keycloak server spamming errors

@garronej
Copy link
Collaborator
garronej commented May 9, 2025

Hello @Dezash,

Thanks for looking into this!
Unfortunately, it's a bit too much work on my end to reproduce the issue as-is.

What would really help is if you could:

  1. Fork the keycloakify-starter repo.
  2. Configure startKeycloakOptions.extensionJars in vite.config.ts to use your custom provider.
  3. Run npx keycloakify start-keycloak once.
  4. Make the necessary changes to the realm using the Keycloak admin UI.

The changes will then be persisted in .keycloakify/realm-26.json.

From there, please share the exact sequence of commands I can use to reproduce the bug.
Once I have that, I should be able to identify and fix the issue.

Relevant docs:

P.S. Are you actually using kcContext.hidpd in your Keycloakify theme?
If not, you can safely exclude it using kcContextExclusionsFtl:
https://docs.keycloakify.dev/features/compiler-options/kccontextexclusionsftl

@Dezash
Copy link
Author
Dezash commented May 10, 2025

I created a fork as requested: https://github.com/Dezash/keycloakify-starter

Steps to reproduce:

  1. Go to localhost:8080/realms/myrealm/account
  2. Enter "testuser" and click "Sign In"
  3. Observe the errors

P.S. Are you actually using kcContext.hidpd in your Keycloakify theme?

We use hidpd in hidpd-select-idp.ftl and webauthn-authenticate.ftl
On Monday, I will try adding the exclusion for login-username.ftl since that seems where the error originates from.

@garronej
Copy link
Collaborator
8000

Thank you @Dezash for taking the time to produce a reproduction repo.

I can reproduce indeed so I should be able to fix or, worst case cenario, provide a workaround.

I'll keep you posted.

@Dezash
Copy link
Author
Dezash commented May 15, 2025

I tried excluding the hidpd parameter, but keycloak still gets stuck:

       kcContextExclusionsFtl: `
         <#if (
             [
                 "hidpd"
             ]?seq_contains(key) &&
             areSamePath(path, ["realm"])
         )>
             <#continue>
         </#if>
       `

@garronej
Copy link
Collaborator

Each time I have an hour to spare I try getting to the bottom on this bug but it's tricky because I'm shoting bullets in the dark.
I'll get to the bottom of this eventually, hopefully by the end of the weekend.

What I can tell you right now is that the exclude pattern you tried to implement do not work because the key is on kcContext.hipd not kcContext.realm.hidp.

It should be:

       kcContextExclusionsFtl: `
         <#if (
             "hidpd" == key &&
             areSamePath(path, [])
         )>
             <#continue>
         </#if>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
0