Giter Site home page Giter Site logo

keycloak-user-migration's Introduction

Hi there

I'm an experienced web developer, focusing on software craftsmanship and good architecture. I'm also a big believer in Open Source Software, which is why I share my work on GitHub, as well as on https://codesoapbox.dev, where you can read my articles about software development.

Preferred Technologies & Tools

Languages

Java Typescript

Frameworks

Spring Boot Hibernate JUnit Angular

Tools

PostgreSQL Docker Maven Git Sonarqube Intellij Linux Elasticsearch Elastic Stack Grafana

Methodologies

Software Craftsmanship Extreme programming Test Driven Development Domain Driven Design Agile Software Development CI/CD

GitHub Stats based on public contributions

Top languages Github stats

Favourite projects I work on

dummy4j keycloak-user-migration

Find me on

Code Soapbox Linkedin Stack Overflow

Built With

keycloak-user-migration's People

Contributors

actions-user avatar badrange avatar c15yi avatar codycraven avatar daniel-frak avatar dependabot[bot] avatar george-tsaplin avatar guy-incognito avatar jpatters avatar little-pinecone avatar ndeitch avatar niveau0 avatar pschichtel avatar renovate[bot] avatar rfeijolo avatar stevenscg avatar toddkazakov avatar weltonrodrigo avatar weltonrodrigotorres avatar xgp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keycloak-user-migration's Issues

Provider isn't used when configured on imported realm

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:

  1. add and configure the migration provider in the User federation section of the Keycloak Admin UI
  2. test it by logging in to the account console with a user in the remote system -- migration provider gets used and works.
  3. export the realm as json
  4. delete the realm
  5. import the realm from the json in step 3
  6. test again like step 2 -- nothing indicates the migration extension is getting used. normal user not found error.
  7. deactivate and activate the migration provider in the Keycloak Admin UI
  8. test again like step 2 -- migration provider gets used and works

Has anyone seen a similar behavior? Any ideas why it would need to get disabled/enabled after a realm import so it gets used?

Swagger is not working

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"}

Fallback to Provider Password if Keycloak internal password is wrong

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:

  1. User A does not exist in Keycloak yet
  2. User A enters his password "1" into the login form of keycloak
  3. This plugin calls the REST GET endpoint getting the user info
  4. This plugin calls the REST POST endpoint validating the password
  5. Keycloak creates the user (with the password "1") inside its database
  6. User can login
  7. User changes his password in the legacy system to "2"
  8. User tries to login again using "2" as their password
  9. Without even calling the REST POST endpoint, keycloak complains about a wrong password.

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?

Other legacy system examples?

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!

create release asset?

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.

Cannot reach api via http in kubernetes

Hi,

if I want to include the plugin into our environment i could normally reach the api via a kubernetes service hostname with http internally.

It turns out that plain http seems to be not called by your rest client. If I switch to https there is some call in the log.

image

Issue with keycloak 9

Hello 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 !

Docker is required??

Doker is required to run this project, any other alternative way to run this project?

Bypassing password complexity requirements on import

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:

image

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?

Basic Authentication Error

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

[BUG] Resetting password randomly locks user out of Keycloak, returning 403 for "GET /admin/serverinfo" request

Versions and logs

Steps to reproduce:

  1. Execute docker-compose up -d in the /docker folder of this repository.
  2. Go to http://localhost:8024/admin/master/console/#/master/user-federation
  3. Log in as admin:admin.
  4. Click Add User migration using a REST client providers.
  5. Use any name for the provider.
  6. Use http://legacy-system-example:8080/user-migration-support as "Rest client URI".
  7. Click "Save".
  8. Go to http://localhost:8024/admin/master/console/#/master/realm-settings/login
  9. Enable "Forgot password".
  10. Go to http://localhost:8024/admin/master/console/#/master/realm-settings/email
  11. Use [email protected] as "From"
  12. Use mailhog as "Host"
  13. Use 1025 as "Port".
  14. Click "Save".
  15. Sign out.
  16. Go to http://localhost:8024
  17. Click "Forgot password?"
  18. Input [email protected] as the username.
  19. Click "Submit".
  20. Go to http://localhost:8025.
  21. Open the e-mail and click "Link to reset credentials".
  22. Press "Submit".
  23. Use password as the new password (this is the existing password).
  24. Click "Submit".

Expected result

The password is always changed and the user is logged in.

Actual result

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.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

docker-compose
docker/docker-compose-sonar.yml
docker/docker-compose.yml
dockerfile
docker/keycloak/Dockerfile
docker/legacy-system-example/Dockerfile
github-actions
.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
maven
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
maven-wrapper
.mvn/wrapper/maven-wrapper.properties
  • maven 3.9.8
docker/legacy-system-example/.mvn/wrapper/maven-wrapper.properties
  • maven 3.9.8
npm
docker/e2e/package.json
  • cypress ^13.10.0
  • cypress-mailhog ^2.0.0
  • quoted-printable ^1.0.1

  • Check this box to trigger a request for Renovate to run again on this repository

Join user to groups

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:

  • Group Mapping
  • Migrate unmapped groups
  • Update user DTO with groups set (optional)
  • Update documentation

Not able to recreate migrated users

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:

  1. Migrate the user
  2. Remove the user in Keycloak
  3. Recreate the user via the Admin UI

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?

Mobile Number support?

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?

There are no requests made to the legacy API endpoint

Describe the bug

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.

Some indications:

  1. Keycloak logs WARN message
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
  1. The API endpoint logging is silent, no request gets logged.

To Reproduce

1. Keycloak

  • install Keycloak application with provided docker-compose file
  • open http://localhost:8024 and login with admin user
  • add new realm DemoRealm, use defaults (not sure if this is mandatory, though)
  • add new client DemoRealm, use defaults (not sure if this is mandatory, though)
  • create new User Federation โ€บ User Migration Using A REST Client as per instructions in the README
  • add http://localhost:3000/auth/ in the Rest client URI filed

Note: I'm not sure if legacy user should authenticate against Master realm, so I created a new realm.

2. Rest API endpoint

3. Login

Expected behavior

  • there should be a log entry in the node console describing each GET or POST request
  • the user bob should be able to log in

Legacy Password Policy Error

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

rest api doesnt import wp users

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?

Keycloak X - java.lang.ClassNotFoundException

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

Keycloak 17 (jboss): java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64

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>

doesnt synchronize users

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?

301 redirect when a request is sent without slash

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

Reproduction

Add an endpoint that requires slash and return the 301 statuscode

Federation Cache Expiration Issues and Docs Clarification

/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.

No defense against brute force attacks [enhancement idea]

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.

Support requiredActions while migrating user to keycloak

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

Turn into Kotlin ?

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.

Username with uppercase letters causing errors

Summary

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.

Steps to reproduce

  • On the GET API side, return a user model with an uppercase letter on their username
    {
      "id": "123",
      "username": "[email protected]",
      "email": "[email protected]",
      "firstName": "Alice",
      // ...
    }

What you expected would happen

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)

What actually happens

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.

Notes

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.

Duplicate migrated users in systems that allow username change

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.

Reproduction steps

  1. In a Keycloak instance that allows username changes
  2. Authenticate with a user found in the REST API
  3. Change username of user
  4. Sign out
  5. Authenticate with original user credentials found in step 2 (this migrates the user again)
  6. Sign in to Keycloak as admin user for realm and check users, observe both users exist - original username and changed username

Tested resolution

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.

Error: unable to find valid certification path to requested target

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?

Rest Client URI is not invoked. Nothing is logs related to this plugin

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
image

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?

image

image

Plugin migrating users without password validation

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!!

User migration with Keycloak 12.X

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!

KC UI fails if migration API isn't running (dev mode)

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 -

  • red error on UI
  • user not created

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

Legacy role conversation fields becomes empty after save

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?

User attributes are not migrating

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"]
    }
}

Migration error / issues after we updated to Keycloak 18 and later 19

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

KC18_log_002 (1).txt

Add support for Client Roles

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;
                }
            }
        }

License?

Just curious what the license of this is. Would you mind adding one please?

Unable to migrate users to a subgroup

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?

Error in using federation

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)

Unsupported class file major version 61 under Java 17

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.

Migration of users with Identity Providers

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?

migration via rest doesnt show up in user federation

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:

grafik

Additional Info:

Keycloak Server info:

Version
24.0.4

do you guys know what i am doing wrong?

Reset password doesn't work

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?

image

Uncaught server error

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

User data migrated although password validation endpoint (POST) returns response with status NOT 200

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.

Support fort 23.X

Hello,

We are on 23.0.5. Is your provider compatible or do you plan to support it ?

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.