Context: Keycloak 1.9.1.Final and newer versions
Hi,
I have created a custom user federation provider which is a simple variation of the Keycloak's classpath property federation provider example. Instead of reading the usernames in a property file, I fetch then from an external web service.
My trouble is that sometimes I get the following exception when trying to authenticate with a test user:
Failed authentication: java.lang.IllegalStateException: Cannot access delegate without a transaction
at org.keycloak.models.cache.infinispan.UserCacheSession.getDelegate(UserCacheSession.java:78)
at org.keycloak.models.cache.infinispan.UserCacheSession.addUser(UserCacheSession.java:442)
at com.example.keycloak.MyFederationProvider.getUserModel(MyFederationProvider.java:324)
at com.example.keycloak.MyFederationProvider.getUserByUsername(MyFederationProvider.java:206)
at org.keycloak.models.UserFederationManager.getUserByUsername(UserFederationManager.java:237)
at org.keycloak.models.utils.KeycloakModelUtils.findUserByNameOrEmail(KeycloakModelUtils.java:273)
at org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator.validateUserAndPassword(AbstractUsernameFormAuthenticator.java:127)
at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.validateForm(UsernamePasswordForm.java:56)
at org.keycloak.authentication.authenticators.browser.UsernamePasswordForm.action(UsernamePasswordForm.java:49)
at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:84)
at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:759)
at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:359)
at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:341)
at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:386)
...
I can't figure out why this exception occures. I looked at the org.keycloak.models.cache.infinispan.UserCacheSession class and I could see that the exception is thrown when transactionActive variable is false, but I don't understand under what conditions it is set to false.
I tried forcing a transaction with KeycloakModelUtils.runJobInTransaction() method or by adding begin() and commit() arround the addUser() call, but it didn't solved the issue (I got a new error which informs that transaction is already active).
Did you already experienced this exception and know how to avoid it ?
Thanks a lot
I think I could find my error (or at least a workarround).
The getInstance() method of my user federation provider was always returning the same object (a singleton). I updated it in order to make it create a new provider every time the method is called.
This seems to solve the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With