daniel-frak / keycloak-user-migration Goto Github PK
View Code? Open in Web Editor NEWA Keycloak plugin for migrating users from legacy systems
License: MIT License
A Keycloak plugin for migrating users from legacy systems
License: MIT License
Doker is required to run this project, any other alternative way to run this project?
I face the issue that I'm not able to recreate users which exist in the legacy system.
One of the scenarios that I'm testing is:
What happens is that in UserResource#createUser there is a check whether the user exists getUserByUsername => this would end up in the overriden method in the newly defined provider, finds the user in the legacy system and tries to create it.. but then then a rollback of the transaction would happen because of:
if (session.users().getUserByUsername(realm, username) != null) {
throw ErrorResponse.exists("User exists with same username");
}
in the UserResource method..
Any workaround for this?
Our legacy system already supports logins with a number of Identity Providers. In Keycloak we would like to support the same identity providers, so we must also be able to migrate users with these identities. I don't see anything in the documentation about this, is it supported?
I have followed the documentation and created API in the legacy system, user creation is happening in Keycloak successfully, but attributes not migrating refer below response
Keycloak version: 11.0.2
{
"id": null,
"username": "example2",
"email": "[email protected]",
"firstName": "example2",
"lastName": "kumar",
"enabled": true,
"emailVerified": true,
"roles": ["ROLE_ADMIN"],
"attributes": {
"VALUE": [ "V1","V2","V3"],
"KEY": ["K1","K2","K3"]
}
}
Hi, thanks for the lib!
Did you think about join users to groups during creation? We've a use case for this and I'm able to create a PR for it, but first I'd like to hear what you think about it.
I checked keycloak's UserModel interface, and there is a joinGroup
method I think calling this method do the job. My doubt is what happens if group doesn't exist.
Thanks
Requirements:
Hi,
Context and dependency injection no longer enabled to JAX-RS Resources
Source: https://www.keycloak.org/2023/07/keycloak-2200-released
Do you plan to support keycloak 22 ?
TL;DR: Error migrating users to keycloak when the username is not all lowercase.
In our API, given a user with username [email protected]
(we're using the email as username).
When they're first migrated to keycloak using the provider, we got the following error in the logs
2024-03-18 10:43:10,361 WARN [org.keycloak.services] (executor-thread-1148) KC-SERVICES0013: Failed authentication: java.lang.IllegalStateException: Local and remote users differ: [[email protected] != [email protected]]
2024-03-18 10:43:10,359 INFO [com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory] (executor-thread-1148) Creating user model for: [email protected]
The user is created in keycloak, but the only info they have is the username, everything else is blank.
{
"id": "123",
"username": "[email protected]",
"email": "[email protected]",
"firstName": "Alice",
// ...
}
The user with username [email protected]
is created on keycloak with all the information provided on the json from the API (even a username [email protected]
would be accepted in this case)
A user is created on keycloak with the username [email protected]
with the status disabled
, no other information is migrated (email, firstname, lastname, attributes, credentials, ...)
The user is not able to login.
We've tracked it to this part of code
As a hack, we're now forcing the username to be all lowercase in the GET api, and it's working fine.
Hi Daniel,
I have a local docker-compose KC 19.0.1 with plugin loaded, and noticed when setting up users in the KC UI that create user fails if the migration API isn't available -
Error logged is
2023-02-25 02:47:47,382 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-13) Uncaught server error: com.danielfrak.code.keycloak.providers.rest.exceptions.RestUserProviderException: com.danielfrak.code.keycloak.providers.rest.rest.http.HttpRequestException: An error occurred while making a HTTP request: GET http://host.docker.internal:5000/api/usermigration/[email protected] HTTP/1.1
With the API running, creating a new user works ok, even if the API returns a non-200 code.
Is this behaviour by design? The concern is KC availability will be impacted, e.g. whenever the API is being deployed.
What would you advise? Thanks v much for a fantastic utility!
Ken
Hello,
We are on 23.0.5. Is your provider compatible or do you plan to support it ?
Thank you.
/I have just done a PoC on using this provider to pull its users (via the legacy REST API, the 2 required endpoints) from a SQL database in the background. I just managed to get my container up and running to serve the endpoint and at first go, seems to work a treat.
I'm a bit confused however.
The documentation says:
As the user has been found, its counterpart will be created in Keycloak and a federation link to the legacy system will be created for it. That way, there will no longer be a need to make the GET request again (but all credential checks will still go through the legacy system). After creating the user, a POST request will be performed to http://www.old-legacy-system.com/auth/bob, with the body:
It further says:
As this is the correct password, the user will be logged in. After the first successful login, the federation link to the legacy system is severed and any interactions with the user will be done completely through Keycloak.
I was hoping it was going to be the first one, but having sniffed the API -> SQL traffic; once the user is first sync'ed - I see no subsequent requests - whether I try a good or bad password. Is this intended? Just looking for some clarity or possible workarounds.
I see that the Federation settings has a cache setting. I tried setting it to 60000 milliseconds (1 minute) or EXPIRE_DAILY a few minutes ahead of my testing, hoping to see the Provider ask the legacy system again - but I'm not seeing it come back to query. In other words, it doesn't feel like they are respected?
Under the "Actions" menu in User Federation - there are 2 Sync buttons. If I click on either, it says the sync is already in progress - however I see no evidence of that. In applications or on the wire.
Would really hurt my migration if during the transition period (of many months) - if the password changes in the SQL database/legacy system, at first glance, it does not appear to sync after first logon. Or "expire" them to force a new request to the legacy REST API for password validation.
Any hint?
Thanks.
Hello, what Java version are we supposed to use to compile this plugin?
I'm not a Java guy by any means, so apologies if this is a dumb question, but I haven't seen it mentioned anywhere in the docs.
I'm getting Unsupported class file major version 61
when executing the tests with these versions of Java and Maven:
> java --version
java 17.0.3.1 2022-04-22 LTS
Java(TM) SE Runtime Environment (build 17.0.3.1+2-LTS-6)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.3.1+2-LTS-6, mixed mode, sharing)
> mvn --version
Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0)
Maven home: d:\dev\bin\apache-maven-3.8.5
Java version: 17.0.3.1, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-17.0.3.1
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
Here's the full build log:
> .\mvnw.cmd clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ---< com.danielfrak.code.keycloak.providers:keycloak-rest-provider >----
[INFO] Building keycloak-rest-provider 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ keycloak-rest-provider ---
[INFO] Deleting D:\dev\keycloak-cp-theme\keycloak-user-migration\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ keycloak-rest-provider ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ keycloak-rest-provider ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 12 source files to D:\dev\keycloak-cp-theme\keycloak-user-migration\target\classes
[WARNING] /D:/dev/keycloak-cp-theme/keycloak-user-migration/src/main/java/com/danielfrak/code/keycloak/providers/rest/LegacyProvider.java: D:\dev\keycloak-cp-theme\keycloak-user-migration\src\main\java\com\danielfrak\code\keycloak\providers\rest\LegacyProvider.java uses or overrides a deprecated API.
[WARNING] /D:/dev/keycloak-cp-theme/keycloak-user-migration/src/main/java/com/danielfrak/code/keycloak/providers/rest/LegacyProvider.java: Recompile with -Xlint:deprecation for details.
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ keycloak-rest-provider ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\dev\keycloak-cp-theme\keycloak-user-migration\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ keycloak-rest-provider ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 12 source files to D:\dev\keycloak-cp-theme\keycloak-user-migration\target\test-classes
[WARNING] /D:/dev/keycloak-cp-theme/keycloak-user-migration/src/test/java/com/danielfrak/code/keycloak/providers/rest/remote/TestUserModel.java: D:\dev\keycloak-cp-theme\keycloak-user-migration\src\test\java\com\danielfrak\code\keycloak\providers\rest\remote\TestUserModel.java uses or overrides a deprecated API.
[WARNING] /D:/dev/keycloak-cp-theme/keycloak-user-migration/src/test/java/com/danielfrak/code/keycloak/providers/rest/remote/TestUserModel.java: Recompile with -Xlint:deprecation for details.
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ keycloak-rest-provider ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.danielfrak.code.keycloak.providers.rest.ConfigurationPropertiesTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.07 s - in com.danielfrak.code.keycloak.providers.rest.ConfigurationPropertiesTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.exceptions.RestUserProviderExceptionTest
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 s - in com.danielfrak.code.keycloak.providers.rest.exceptions.RestUserProviderExceptionTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.LegacyProviderFactoryTest
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.832 s - in com.danielfrak.code.keycloak.providers.rest.LegacyProviderFactoryTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.LegacyProviderTest
giu 08, 2022 9:15:50 AM com.danielfrak.code.keycloak.providers.rest.LegacyProvider lambda$getUserModel$2
WARN: User not found in external repository: user
giu 08, 2022 9:15:50 AM com.danielfrak.code.keycloak.providers.rest.LegacyProvider lambda$getUserModel$2
WARN: User not found in external repository: user
[INFO] Tests run: 17, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.372 s - in com.danielfrak.code.keycloak.providers.rest.LegacyProviderTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.remote.LegacyUserTest
[ERROR] Tests run: 11, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.102 s <<< FAILURE! - in com.danielfrak.code.keycloak.providers.rest.remote.LegacyUserTest
[ERROR] testEquals Time elapsed: 0.098 s <<< FAILURE!
java.lang.AssertionError:
EqualsVerifier found a problem in class com.danielfrak.code.keycloak.providers.rest.remote.LegacyUser.
-> Unsupported class file major version 61
For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
at com.danielfrak.code.keycloak.providers.rest.remote.LegacyUserTest.testEquals(LegacyUserTest.java:95)
Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 61
at com.danielfrak.code.keycloak.providers.rest.remote.LegacyUserTest.testEquals(LegacyUserTest.java:95)
[INFO] Running com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactoryTest
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory lambda$getGroupModel$6
INFO: Found existing group group with id 12345
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory lambda$getGroupModel$7
INFO: Created group null with id null
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory lambda$getGroupModel$7
INFO: Created group null with id null
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory lambda$getGroupModel$6
INFO: Found existing group newGroup with id null
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
giu 08, 2022 9:15:51 AM com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory create
INFO: Creating user model for: user
[INFO] Tests run: 17, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.279 s - in com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactoryTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.rest.http.HttpClientTest
[INFO] Tests run: 26, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.754 s - in com.danielfrak.code.keycloak.providers.rest.rest.http.HttpClientTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.rest.http.HttpRequestExceptionTest
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.003 s - in com.danielfrak.code.keycloak.providers.rest.rest.http.HttpRequestExceptionTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.rest.http.HttpResponseTest
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 s - in com.danielfrak.code.keycloak.providers.rest.rest.http.HttpResponseTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.rest.RestUserServiceTest
[INFO] Tests run: 22, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.55 s - in com.danielfrak.code.keycloak.providers.rest.rest.RestUserServiceTest
[INFO] Running com.danielfrak.code.keycloak.providers.rest.rest.UserPasswordDtoTest
[ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.003 s <<< FAILURE! - in com.danielfrak.code.keycloak.providers.rest.rest.UserPasswordDtoTest
[ERROR] equalsContract Time elapsed: 0 s <<< FAILURE!
java.lang.AssertionError:
EqualsVerifier found a problem in class com.danielfrak.code.keycloak.providers.rest.rest.UserPasswordDto.
-> Unsupported class file major version 61
For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
at com.danielfrak.code.keycloak.providers.rest.rest.UserPasswordDtoTest.equalsContract(UserPasswordDtoTest.java:28)
Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 61
at com.danielfrak.code.keycloak.providers.rest.rest.UserPasswordDtoTest.equalsContract(UserPasswordDtoTest.java:28)
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] LegacyUserTest.testEquals:95 EqualsVerifier found a problem in class com.danielfrak.code.keycloak.providers.rest.remote.LegacyUser.
-> Unsupported class file major version 61
For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
[ERROR] UserPasswordDtoTest.equalsContract:28 EqualsVerifier found a problem in class com.danielfrak.code.keycloak.providers.rest.rest.UserPasswordDto.
-> Unsupported class file major version 61
For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
[INFO]
[ERROR] Tests run: 106, Failures: 2, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.502 s
[INFO] Finished at: 2022-06-08T09:15:53+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project keycloak-rest-provider: There are test failures.
[ERROR]
[ERROR] Please refer to D:\dev\keycloak-cp-theme\keycloak-user-migration\target\surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
There are a few warnings, but the bigger problem seems to be that maven-surefire-plugin:2.22.2
doesn't like Java 17.
Again, not a Java guy so I'm stumped. Do I need an older version? Am I good to use the artifacts I find in the target
directory anyway? Because that would be enough.
Thanks for any help.
First of all, great plugin! Works very well in general and really helps smooth over the migration.
However, I noticed that if you have a password policy in place, if a password from the legacy system doesn't meet that criteria, it throws an error. The user is created but without a password and without the ability to update their password, so effectively locked out.
It would be great to allow the legacy password to bypass the password policy since its updated straight away anyway.
Keycloak version: 12.0.4
Hi,
Was looking for some advice really. I have a use case where I need to start migrating users from SQL to KeyCloak and this provider works perfect. The project demands that a more stricter password complexity requirement be enforced on KC, then that which was set in SQL land (by the application being migrated to KeyCloak auth).
Say the new password complexity in KC limited the amount of chars to 10, but I have a password in SQL of 12 chars.. the import process fails because it does not meet the password complexity requirements of KC.
I see this method:
And it seems that when PasswordPolicy isn't met, it will skip updating the credential and then its supposed to then set UPDATE_PASSWORD and force the user into a new password flow, but that doesn't seem to occur. Furthermore, the lack of a password breaks some other areas/flows/providers for me.
When I try to remove or override PasswordDoesNotBreakPolicy to be true and the code proceeds to userModel.credentialmanager().updateCredential - the problem persists. I believe this is because credentialmanager (a base implement of KC as opposed to this repos), validates password complexity yet again?
It also seems impossible to overwrite anything in "CredentialInput input" that is passed into this method with a password of my choice (and then set UPDATE_PASSWORD).
I looked at KC API docs and eventually landed on attempting to make my own CredentialInput object, but for that I need a new UserCredentialModel (https://www.keycloak.org/docs-api/22.0.4/javadocs/org/keycloak/models/UserCredentialModel.html). It has a nested class of type PasswordUserCredentialModel. When I attempt to create a PasswordUserCredentialModel, mvn build says that it is private and can't be used here.
So I'm in a bit of a loss. I want to keep password policy requirements on, but I still need to successfully import users who do not meet it (yet) and take them thru a password update process. Since other things don't seem to like not having a password set, I just want to set it to a random string that meets my new password complexity requirements (thereby allowing the process to finish) and immediately take the user thru a password update process.
Any ideas on how I might accomplish this?
Fields like 'Console display name' and 'Rest client URI (required)' is filled, but legacy conversations empty.
Keycloak (in docker) version 20.0.2, 21.0.2
I've missed something in keycloak configuration or docker image settings?
The plugin is installed and working correctly, but when a user tries to do "reset pasword" I see an error "An unexpected error has occurred". Investigating debug logs on the server, I see a SQL error that a duplicate entry (of a user record with the same email address) is attempted to be created. Has anybody else tried reset password with this plugin?
ForbiddenException
being throwndocker-compose up -d
in the /docker
folder of this repository.http://localhost:8024/admin/master/console/#/master/user-federation
admin:admin
.Add User migration using a REST client providers
.http://legacy-system-example:8080/user-migration-support
as "Rest client URI".http://localhost:8024/admin/master/console/#/master/realm-settings/login
http://localhost:8024/admin/master/console/#/master/realm-settings/email
[email protected]
as "From"mailhog
as "Host"1025
as "Port".http://localhost:8024
[email protected]
as the username.http://localhost:8025
.password
as the new password (this is the existing password).The password is always changed and the user is logged in.
Sometimes, something bad happens after going through the "reset password procedure", and every call to http://localhost:8024/admin/serverinfo
fails with 403, making it so that the user is effectively locked out of the account.
I found a strange behavior, and I can't figure out from the code if it's an extension problem or a Keycloak problem.
To reproduce:
Has anyone seen a similar behavior? Any ideas why it would need to get disabled/enabled after a realm import so it gets used?
In systems that require the path in the url to have a slash, it immediately returns a status code 301, the provider is not prepared to deal with this redirection and interrupts the execution
Add an endpoint that requires slash and return the 301 statuscode
If the role is defined in keycloak as a Client Role rather than Realm Role it is not migrated
Adding something like the code below would make it look through client roles.
RoleModel roleModel = realm.getRole(role);
if(roleModel == null) {
List<ClientModel> clients = realm.getClients();
for(ClientModel client : clients) {
roleModel = client.getRole(role);
if(roleModel != null) {
break;
}
}
}
I did the steps in the explanations with the example rest in the project, but when I want to log in with the user information, it does not see the users. I wrote a new rest service, likewise, it does not synchronize users and does not transfer them to keycloak. Where could I be doing wrong?
I launched the demo version via Docker Compose. Swagger is not working;
➜ docker git:(master) ✗ curl -L http://localhost:8080/swagger-ui.html
{"timestamp":"2024-01-09T08:58:03.388+00:00","status":404,"error":"Not Found","path":"/swagger-ui.html"}
Really nice and clean work guys,
If you want to move to the next level I can turn it into Kotlin for you, it will remove tons of boilerplate code.
Give me a green-light if you want me to do it.
The issue with the new Admin UI should be fixed with Keycloak 20 release : keycloak-ui#3341
Initially, the plugin worked fine, but then after some time Basic Authentication stopped working. As far as I am aware, no changes were made to the server to initiate this error.
Keycloak version: 12.0.4
2021-06-05 15:57:45,888 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-6) Uncaught server error: java.lang.NoClassDefFoundError: org/jboss/resteasy/client/jaxrs/internal/BasicAuthentication at deployment.keycloak-user-migration.jar//com.danielfrak.code.keycloak.providers.rest.rest.RestUserService.registerBasicAuthFilter(RestUserService.java:40) at deployment.keycloak-user-migration.jar//com.danielfrak.code.keycloak.providers.rest.rest.RestUserService.<init>(RestUserService.java:30) (...) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: java.lang.ClassNotFoundException: org.jboss.resteasy.client.jaxrs.internal.BasicAuthentication from [Module "deployment.keycloak-user-migration.jar" from Service Module Loader] at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:255) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) ... 103 more
Are there any plans to support Keycloak version 19?
For example we can add CONFIGURE_TOTP required action if in legacy system User was using OTP feature, but we cannot migrate it to keycloak as is. By adding such required action we will ask user to reconfigure OTP for keycloak on first login
Hello again. sorry for spamming this repo but still need some help. I managed to install the plugin. But it seems the plugin doesnt import my wp users.
I used this rest point
/* Create Custom Endpoint */
add_action('rest_api_init', 'create_keycloak_endpoints');
function create_keycloak_endpoints() {
register_rest_route(
'wp/v2',
'/keycloak-user-migration/(?P<username>.+)',
[
'methods' => 'GET',
'callback' => 'keycloak_get',
]
);
register_rest_route(
'wp/v2',
'/keycloak-user-migration/(?P<username>.+)',
[
'methods' => 'POST',
'callback' => 'keycloak_post',
]
);
}
function keycloak_get($request) {
$username = $request['username'];
$user = get_user_by('email', $username);
if (!$user) {
$user = get_user_by('login', $username);
}
if (!$user) {
write_log('not found '.$username);
return new WP_REST_Response(['message' => 'not found '.$username], 404);
}
return [
'id' => $user->ID,
'username' => $user->user_login,
'email' => $user->user_email,
'firstName' => $user->user_firstname,
'lastName' => $user->user_lastname,
'enabled' => true,
'emailVerified' => true,
];
}
function keycloak_post($request) {
$username = $request['username'];
$password = $request['password'];
$user = get_user_by('login', $username);
if (!$user) {
$user = get_user_by('email', $username);
}
if (!$user || !wp_check_password($password, $user->user_pass, $user->ID)) {
write_log('wrong_password for '.$username);
return new WP_REST_Response(['message' => 'wrong_password for '.$username], 404);
}
return true;
}
if (!function_exists('write_log')) {
function write_log($log) {
if (is_array($log) || is_object($log)) {
error_log(print_r($log, true));
} else {
error_log($log);
}
}
}
and I can also call it with
`curl -X GET "https://mydomain.com/wp-json/wp/v2/keycloak-user-migration/testuser"
which gives me a correct response.
But using the url in the plugin: https://mydomain.com/wp-json/wp/v2/keycloak-user-migration
with and without /
doesnt work.
I dont get any logs on keycloak, nor on wp if there is errors during calls.
When I try to syncronize, it says skipped syncronziation as synchronisation is beeing processed
What am I doing wrong again? Any hints?
In systems that allow usernames to change (in my use-case the email address is the username and users may change their email) keycloak-user-migration allows migration user accounts to be created multiple times once a user changes their username.
I was able to solve this scenario by adding a DELETE method to the RestUserClient. I then went to my REST service and added a DELETE method handler that marks the record as being migrated, preventing the user from being able to be migrated again as occurs in step 5 of the reproduction steps.
If you are open to this solution, please let me know and I'll be happy to open a Pull Request.
As a note, it is imperative that #9 is also solved to truly resolve this scenario. Otherwise if the user sets their credential through the forgot password (or other flows as mentioned in the commit message 3354631) the issue described is able to reproduced with similar reproduction steps.
Hi @daniel-frak, I know you've specified that the plugin is only compatible with 9.x and 11.x versions of keycloak (which have worked for me) but i tried using it with keycloak 12.0.2 and 12.03 as well. It seems like an error occurs inside UserModelFactory when the .addUser function is called on the session local storage.
[org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-3) SQL Error: 0, SQLState: null [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-3) IJ031013: Interrupted attempting lock: org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@4e7d7cak4qb7 [org.keycloak.utils.ServicesUtils] (default task-3) Execution with object [com.danielfrak.code.keycloak.providers.rest.LegacyProvider@37c7bed6] exceeded specified time limit 3000. [org.keycloak.services] (default task-3) KC-SERVICES0013: Failed authentication: org.keycloak.models.ModelException: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not prepare statement
But the strange thing is, that if i retry the login with the same user multiple times it actually successfully migrates the user. Have you tried using the plugin and are you aware of this issue and what might be causing it? Do you know why specifically the REST user migration plugin is not compatible with the newer versions of keycloak?
Thanks in advance!
Hello people,
I am trying to integrate this plugin in my current keycloak installation. But I cant get it to work and the migration via rest doesnt show up in the tab user federation.
This is my current docker dompose-compose.yml:
root@ldap-server:~/keycloak-docker-compose# cat docker-compose.yml
version: '3.9'
volumes:
mariadb_data:
driver: local
networks:
local:
ipam:
config:
- subnet: ${SUBNET:-172.16.0.0/29}
services:
mariadb:
image: mariadb:${MARIADB_VERSION:-latest}
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD:-xyz}
MARIADB_DATABASE: keycloak
MARIADB_USER: keycloak
MARIADB_PASSWORD: ${MARIADB_KEYCLOAK_PASSWORD:-xyz}
mem_limit: 300m
mem_reservation: 200m
container_name: mariadb
volumes:
- mariadb_data:/var/lib/mysql
restart: always
networks:
- local
keycloak:
image: quay.io/keycloak/keycloak:${KEYCLOAK_VERSION:-latest}
environment:
KC_DB: mariadb
KC_DB_SCHEMA: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: ${MARIADB_KEYCLOAK_PASSWORD:-xyz}
KC_DB_URL_HOST: mariadb
KEYCLOAK_ADMIN: xyz
KEYCLOAK_ADMIN_PASSWORD: xyz
KC_PROXY: edge
KC_HOSTNAME_STRICT: false
KC_HOSTNAME_URL: https://${KEYCLOAK_DOMAIN}
mem_limit: 500m
mem_reservation: 400m
command: start
container_name: keycloak
volumes:
- ./keycloak/themes:/opt/keycloak/themes
- ./keycloak-rest-provider-4.0.0.jar:/opt/jboss/keycloak/standalone/deployments/keycloak-rest-provider-4.0.0.jar
restart: always
networks:
- local
depends_on:
- mariadb
nginx:
image: nginx:${NGINX_VERSION:-latest}
environment:
KEYCLOAK_DOMAIN: ${KEYCLOAK_DOMAIN}
mem_limit: 50m
mem_reservation: 20m
container_name: nginx
volumes:
- ./nginx/templates:/etc/nginx/templates
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
ports:
- "80:80"
- "443:443"
restart: always
networks:
- local
certbot:
image: certbot/certbot:${CERTBOT_VERSION:-latest}
environment:
CERTBOT_LETSENCRYPT_EMAIL: ${CERTBOT_LETSENCRYPT_EMAIL}
KEYCLOAK_DOMAIN: ${KEYCLOAK_DOMAIN}
mem_limit: 20m
mem_reservation: 10m
container_name: certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
command: certonly --non-interactive --webroot -w /var/www/certbot --email ${CERTBOT_LETSENCRYPT_EMAIL} -d ${KEYCLOAK_DOMAIN} --agree-tos
depends_on:
- nginx
the docker logs doesnt show up any logs that the plugin is loaded.
the container has the jar file mounted:
bash-5.1# pwd
/opt/jboss/keycloak/standalone/deployments
bash-5.1# ls
keycloak-rest-provider-4.0.0.jar
bash-5.1#
I tried to manually write a keycloak-rest-provider-4.0.0.jar.dodeploy
file but it still doesnt work.
My keycloak still looks like this:
Additional Info:
Keycloak Server info:
Version
24.0.4
do you guys know what i am doing wrong?
Hi! Thanks for the great project.
I'm looking to see if you are aware of other legacy system examples? I see the example in the legacy-system-example
dir, but I wanted to check if you were aware of others in the wild. I'm working with people that are using Django and Passport (username-password strategy) and wanted to check before I build them.
Thank you!
Good evening all,
First of all thanks for the wonderful plugin, which is what we exactly needed right now,
when we try to install this plugin in our existing keycloak we get the following error, can someone guide me the right direction what am i doing wrong
2022-12-22 14:55:24,695 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-586) Uncaught server error: java.lang.NoSuchMethodError: 'java.lang.String org.keycloak.common.util.Encode.urlEncode(java.lang.String)'
at com.danielfrak.code.keycloak.providers.rest.rest.RestUserService.findLegacyUser(RestUserService.java:73)
at com.danielfrak.code.keycloak.providers.rest.rest.RestUserService.findByUsername(RestUserService.java:67)
at com.danielfrak.code.keycloak.providers.rest.LegacyProvider.lambda$getUserByUsername$3(LegacyProvider.java:155)
at com.danielfrak.code.keycloak.providers.rest.LegacyProvider.getUserModel(LegacyProvider.java:51)
at com.danielfrak.code.keycloak.providers.rest.LegacyProvider.getUserByUsername(LegacyProvider.java:155)
at org.keycloak.storage.UserStorageManager.lambda$getUserByUsername$16(UserStorageManager.java:334)
at org.keycloak.utils.ServicesUtils.lambda$timeBoundOne$1(ServicesUtils.java:84)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:400)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:503)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
Hello,
I'm testing the plugin for user data migration to Keycloak. Almost all works fine, except the case when the user is found (the GET end point), but the password is invalid (POST end-point).
The first endpoint returns "ResponseEntity" with the user data and "HttpStatus.OK".
The second endpoint returns "ResponseEntity" with "HttpStatus.BAD_REQUEST".
What happens is that the user data is transferred to Keycloak and the user is not able to login to the application.
I would expect that if the password endpoint (POST) returns status different than 200, the user data should not be moved to Keycloak at all.
My question is, is it how it is supposed to work, or there is something that is missing?
These are my endpoints:
@GetMapping("/user-client/{username}")
public ResponseEntity<UserData> getUser(@PathVariable("username") String username) {
return new ResponseEntity<>(prepareDummyUser(username), HttpStatus.OK);
}
@PostMapping("/user-client/{username}")
public ResponseEntity validatePassword(@PathVariable("username") String username, @RequestBody Password password) {
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}
The user data is not migrated only when the first (GET) endpoint returns HttpStatus.BAD_REQUEST.
I tested in Keycloak 16.1 and 15.1, with the X distribution:
keycloak_1 | 2021-12-30 13:03:08,821 WARN [org.key.services] (executor-thread-66) KC-SERVICES0013: Failed authentication: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.glassfish.jersey.client.JerseyClientBuilder
keycloak_1 | at javax.ws.rs.client.ClientBuilder.newBuilder(ClientBuilder.java:102)
keycloak_1 | at javax.ws.rs.client.ClientBuilder.newClient(ClientBuilder.java:113)
keycloak_1 | at com.danielfrak.code.keycloak.providers.rest.LegacyProviderFactory.create(LegacyProviderFactory.java:25)
keycloak_1 | at com.danielfrak.code.keycloak.providers.rest.LegacyProviderFactory.create(LegacyProviderFactory.java:15)
keycloak_1 | at org.keycloak.storage.AbstractStorageManager.getStorageProviderInstance(AbstractStorageManager.java:229)
keycloak_1 | at org.keycloak.storage.AbstractStorageManager.lambda$getEnabledStorageProviders$0(AbstractStorageManager.java:98)
keycloak_1 | at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
keycloak_1 | at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:400)
keycloak_1 | at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
........
.....
keycloak_1 | Caused by: java.lang.ClassNotFoundException: org.glassfish.jersey.client.JerseyClientBuilder
keycloak_1 | ... 77 more
keycloak_1 |
keycloak_1 | 2021-12-30 13:03:08,829 WARN [org.key.events] (executor-thread-66) type=LOGIN_ERROR, realmId=local, clientId=zzz-web, userId=null, ipAddress=172.28.0.1, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, redirect_uri=https://zzz.kc.l/, code_id=bde1ebeb-b2ab-4b2a-9c1a-cc201128f2f1, username=zzzzzz, authSessionParentId=bde1ebeb-b2ab-4b2a-9c1a-cc201128f2f1, authSessionTabId=uQEeyvaPdhM
Hello, would you be willing to create a release tag and upload the .jar file as a release asset?
I ask because I am using the keycloak operator which will install an extension for me if I provide it a url to the jar file.
We are experiencing issues with requesting the migration endpoint. The certification path can not be found:
[org.keycloak.services] (default task-1) KC-SERVICES0013: Failed authentication: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The root CA is trusted by default in the jvm cacerts truststore. We have tried importing multiple variants with the full chain and without, but the errors persists. Even when we try to disable the trustmanager, the error persist. Any thoughts?
Hello,
Recently we noticed an issue migrating our users to keycloak using the plugin. Namely, on the first attempt the migration fails with a message: "Unexpected error when handling authentication request to identity provider" . The Keycloak log shows that the database, h2, is crashed (you can see the log). This is however temporary. Then, on the second attempt, after a reload of the login page, when the user gives again the credentials, logs in, he/she gets migrated.
What I can say currently is that when we developed the migration client we were using KC 16/17 and everything was fine.
The problem appeared probably after KC upgrade to version 18, and now for the version 19 still exists.
We are updating the version of the plugin accordingly, so that part as a possible reason is ruled out.
Does anyone have an idea what may be the reason behind the Db crash? And how could we possibly fix this?
Thanks in advance,
Konstantin
Forgive me if I'm being blind but I can't find any reference in the code, and I could have sworn I read here weeks ago about the issue.
I want to import a phone number from SQL during migration into Keycloak v23 or v24 for use with the SMS Authenticator found here:
https://github.com/netzbegruenung/keycloak-mfa-plugins/tree/main/sms-authenticator
I currently have this configured with SQL User Migration using your work and its great! KC is configured to Update the mobile number when it "sees" the user for the first time from the SQL provider. It stores this number as a "Credential" (as opposed to an attribute), but in cleartext.
Is there anyway to make this migration provider populate the credential called Mobile-number?
Just curious what the license of this is. Would you mind adding one please?
I have imported plugin successfully, after RestAPI configuration.
tried to login with unavailable user in Keycloak not get succeed in user migration (no API request trigged from Keycloak). Got below error
Keycloak version: 11.0.1
Once after added this plugin I am not able to create user in realm.
**[Server:server-one] 08:11:28,721 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-2) Uncaught server error: java.lang.NoClassDefFoundError: org/jboss/logging/Logger_**_
it will be really helpful could you please share the module.xml
I have completed the installation of the Keycloak server and the Feredation provider as described in the README file. The problem is that the user from the legacy database does not validate.
The error message from the login form:
We are sorry...
Unexpected error when handling authentication request to identity provider.
From what I can tell there are no requests made to the legacy API endpoint.
keycloak_1 | 15:17:53,532 WARN [org.keycloak.events] (default task-25) type=LOGIN_ERROR, realmId=DemoRealm, clientId=account, userId=null, ipAddress=172.20.0.1, error=invalid_user_credentials, auth_method=openid-connect, auth_type=code, redirect_uri=http://localhost:8024/auth/realms/DemoRealm/account/login-redirect, code_id=e545e494-603e-4f35-8758-765f5fd5527f, username=bob, authSessionParentId=e545e494-603e-4f35-8758-765f5fd5527f, authSessionTabId=izT3E0HXAu8
http://localhost:8024
and login with admin
userDemoRealm
, use defaults (not sure if this is mandatory, though)DemoRealm
, use defaults (not sure if this is mandatory, though)User Federation › User Migration Using A REST Client
as per instructions in the READMEhttp://localhost:3000/auth/
in the Rest client URI
filedNote: I'm not sure if legacy user should authenticate against Master
realm, so I created a new realm.
yarn && yarn start
DemoRealm
account address http://localhost:8024/auth/realms/DemoRealm/accountbob
and password password123
from the data.js
file.GET
or POST
requestbob
should be able to log inHello there is the following error with keycloak 9 :
Uncaught server error: java.lang.NoSuchMethodError: 'boolean org.keycloak.models.UserCredentialManager.updateCredential(org.keycloak.models.RealmModel, org.keycloak.models.UserModel, org.keycloak.credential.CredentialInput)'
Can you please update your plugin ?
Thank you for your work !
I'm unsure how this should work in this plugin, so what the intended behaviour is.
What I would love to achieve, is that the users can change their passwords in the legacy system and still login. As keycloak stores the passwords after a successful login inside its own database, this would require, that, when the password of the user is invalid (from the point of view of the Keycloak Database), this plugin must be asked to check the password again.
I was assuming this is the behaviour, but I'm failing to get this working:
Is this the desired behaviour? Can this be configured, so that in the step 9. keycloak first checks its own database for password matches and if it doesn't find a valid password, asks this plugin?
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
org.keycloak:keycloak-model-storage
, org.keycloak:keycloak-server-spi-private
, org.keycloak.bom:keycloak-spi-bom
)org.junit.platform:junit-platform-engine
, org.junit.jupiter:junit-jupiter
)org.mockito:mockito-core
, org.mockito:mockito-junit-jupiter
)docker/docker-compose-sonar.yml
docker/docker-compose.yml
docker/keycloak/Dockerfile
docker/legacy-system-example/Dockerfile
.github/workflows/maven.yml
actions/checkout v4
actions/setup-java v4
actions/cache v4
actions/cache v4
actions/upload-artifact v4
actions/checkout v4
actions/download-artifact v4
actions/cache v4
actions/setup-node v4
actions/upload-artifact v4
actions/upload-artifact v4
.github/workflows/release.yml
actions/checkout v4
actions/setup-java v4
jasonetco/upload-to-release v0.1.1
mingjun97/file-regex-replace v1
docker/legacy-system-example/pom.xml
org.springframework.boot:spring-boot-starter-parent 3.3.1
org.springdoc:springdoc-openapi-starter-webmvc-ui 2.6.0
pom.xml
org.keycloak.bom:keycloak-spi-bom 25.0.0
org.keycloak:keycloak-server-spi-private 25.0.0
org.keycloak:keycloak-model-storage 25.0.0
org.jboss.logging:jboss-logging 3.6.0.Final
org.junit.jupiter:junit-jupiter 5.10.3
org.junit.platform:junit-platform-engine 1.10.3
org.mockito:mockito-junit-jupiter 5.12.0
org.mockito:mockito-core 5.12.0
com.squareup.okhttp3:mockwebserver 4.12.0
org.apache.httpcomponents:httpclient 4.5.14
nl.jqno.equalsverifier:equalsverifier 3.16.1
org.apache.maven.plugins:maven-surefire-plugin 3.3.1
org.jacoco:jacoco-maven-plugin 0.8.12
org.jacoco:jacoco-maven-plugin 0.8.12
.mvn/wrapper/maven-wrapper.properties
maven 3.9.8
docker/legacy-system-example/.mvn/wrapper/maven-wrapper.properties
maven 3.9.8
docker/e2e/package.json
cypress ^13.10.0
cypress-mailhog ^2.0.0
quoted-printable ^1.0.1
Running Keycloak 21.1.2 and version 1.0.0 of keycloak-user-migration plugin on a kubernetes cluster
I've setup a Rest client using this plugin with no authentication. The url is following, I've redacted the subdomain which I am using.
https://{{redacted}}.ngrok.app/api/external-login
I can login if a user already exists in Keycloak but if the user does not exist then Keycloak or this plugin is not calling the configured REST API endpoint.
I've looked into the logs and I can see that first it generates a SQL query to check if that user exists in the Keycloak db and then after few further log entries, it has another SQL query to insert into EVENT_ENTITY table with the error that user not found.
Between these log entries, I would suspect something from Keycloak or this plugin which invoke this rest endpoint but nothing. There are only other logs which are related to Hibernate.
Attaching the screenshots just to show you that there is nothing related to lazy migration in the logs.
Entry no. 157 2024-03-15T12:10:11.207+00:00
is the SELECT query, trying to find that user in the Keycloak user table.
Entry no. 121 2024-03-15T12:10:11.387+00:00
is the insert into Event_entity table.
What's going on? How do I confirm if this plugin is working or am I missing something?
I am running the current commit of this plugin with the standard Dockerfile of keycloak 15.0.0 in it. I have run all previous commits for test as well.
Initially it all worked fine, and my users have been migrated only after my POST REST legacy endpoint returned 200 for a valid password.
Now, after no changes made, to the best of my knowledge, users are being migrated (although not logged in) without their passwords in case they submit a wrong password (GET returns 200, POST returns 401 for wrong password).
Previously user was not migrated in this situation. Now it is, according to this log:
2021-08-23T22:49:49.521910840Z�[0m�[0m22:49:49,521 INFO [com.danielfrak.code.keycloak.providers.rest.remote.UserModelFactory] (default task-4) Creating user model for: matheusmansour
We can see my REST microservice has been called with POST status code different than 200, nonetheless:
2021-08-23T22:49:49.515833Z **GET200** 964 B39 msApache-HttpClient/4.5.13 (Java/11.0.12) https://facily-wp-user-migration-ch4ssh6qga-uc.a.run.app/auth/matheusmansour
Aviso
2021-08-23T22:49:49.579379Z **POST401** 719 B21 msApache-HttpClient/4.5.13 (Java/11.0.12) https://facily-wp-user-migration-ch4ssh6qga-uc.a.run.app/auth/matheusmansour
Any clue why this might be happening? Been stuck with it for 4 days with code breaking in production and had to turn the plugin off. Thanks very much for any help!!
I built the plugin locally with mvn clean package
and deployed the resulting jar to my keycloak (17.0.1 jboss distribution).
Using it results in:
14:46:37,268 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-4) Uncaught server error: java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64
at deployment.keycloak-rest-provider.jar//com.danielfrak.code.keycloak.providers.rest.rest.http.HttpClient.enableBasicAuth(HttpClient.java:41)
at deployment.keycloak-rest-provider.jar//com.danielfrak.code.keycloak.providers.rest.rest.RestUserService.configureBasicAuth(RestUserService.java:38)
at deployment.keycloak-rest-provider.jar//com.danielfrak.code.keycloak.providers.rest.rest.RestUserService.<init>(RestUserService.java:28)
at deployment.keycloak-rest-provider.jar//com.danielfrak.code.keycloak.providers.rest.LegacyProviderFactory.create(LegacyProviderFactory.java:29)
at deployment.keycloak-rest-provider.jar//com.danielfrak.code.keycloak.providers.rest.LegacyProviderFactory.create(LegacyProviderFactory.java:18)
at [email protected]//org.keycloak.storage.AbstractStorageManager.getStorageProviderInstance(AbstractStorageManager.java:229)
at [email protected]//org.keycloak.storage.AbstractStorageManager.lambda$getEnabledStorageProviders$0(AbstractStorageManager.java:98)
Inspecting the jar shows that these classes are not bundled and apparently are not provided by keycloak. (maybe missing a module.xml ?).
I temporarily added the maven-shade-plugin to bundle the missing (non-provided) dependencies with the plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>org.apache.httpcomponents:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
</excludes>
</filter>
<filter>
<artifact>commons-*:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
There is currently brute force attack detection and mitigation built into Keycloak for existing users. This means that Keycloak keeps a cache of recurring login attempts, and can be configured to lockout user login attempts when it reaches a certain threshold of failures.
Because this is for existing users, it does not help the case where a user is being migrated using the keycloak-user-migration
extension. Because of this, it is possible to bypass this defense, and send unlimited requests to the REST endpoints used by the extension. This presents an attack surface that may be unacceptable to organizations that have policies that require brute force attack detection and mitigation.
A potential enhancement to this extension would be to provide a simplified brute force attack detection and mitigation functionality.
I have a Keycloak installation which contains multiple company groups with subgroups (Owner, Admin, Member).
I am trying to use the plugin to migrate users from the old auth system to the new one and assign the users to the groups for each of the company.
Since assigning to a group is based on the group name I can't find a way to assign a user to a subgroup, especially since the subgroups all have the same name for each company group.
Can you let me know if that is possible with the current implementation?
Wouldn't it be better to use the id instead of the name?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.