I am facing challege when migrating exist google-oauth user data to keycloak. I am currently working on a project involving a microservice architecture, with Keycloak serving as my OpenID Connect (OIDC) authentication provider.
Previously, I had an springboot application where MongoDB was used to store user data, including self-registered and socially logged in (e.g., Google) users. And I am now aiming to centralize the user data source by migrating all user data into the default MySQL schema generated by Keycloak.
My problem is when migrating social login users (google). It appears there is no straightforward way to mark a user as a Google user in Keycloak. For instance, if I migrating a user data which is previously registered by google login with [email protected] via keycloak rest api and then the user attempt a Google login, Keycloak perceives it as a new user and consequently displays an error for duplicate user found. enter image description here
I've researched various migration plans and found that for self-registered users, I can leverage Keycloak's "create user" REST API .This allows me to post user information, including IDs, into Keycloak.But seems it is not the case for google login users.
.html#_users
For context, my original database stores the email, username, and provider (self or Google) and there is no googleId is stored.
My User model originally:
@NoArgsConstructor
@Data
@Document(collection = "User")
@AllArgsConstructor
@Builder
public class User implements UserDetails {
@Id
private String id;
@Field
private String auth_user_id;
@Field
private String encrypted_pwd;
@Field
private String username;
@Field
private String email;
@Field
private String region;
@Field
private LanguageEnum default_language=LanguageEnum.zh_HK;
@Field
private List<Category> prefer_cate=List.of();
@Field
private List<Grade> prefer_grade=List.of();
@Field
private List<String> prefer_tag=List.of();
@Field
private List<RoleEnum> role=List.of(RoleEnum.USER);
@Field
private IdentityEnum identity;
@Field
private String otp;
@Field
private boolean isEnable=false;
@Field
private LocalDateTime otpGeneratedTime;
@Field
private Authprovider provider;
@Field
private String profileUrl;
@Field
private String contact;
@Field
private String address;
@Field
private LocalDateTime created_at;
@Field
private LocalDateTime updated_at;
user data example as json format in mongo:
{
"_id": {
"$oid": "xxxxxxxx"
},
"username": "xxxxx",
"email": "[email protected]",
"default_language": "**",
"prefer_cate": [],
"prefer_grade": [],
"prefer_tag": [],
"role": [
"USER"
],
"otp": "***",
"isEnable": true,
"otpGeneratedTime": {
"$date": "2024-06-13T14:18:05.548Z"
},
"provider": "google",
"profileUrl": "****",
"subscription_plan": "FREE",
}
Given that in the past,I used the field "provider" to identify the user as google login and self register.
I would appreciate any advice, suggestions, or feedback on my current approach. Thank you in advance for your assistance.