How can I distinguish between a Social Login and an Email Login in User Storage SPI?

Basically try to figure out whether user is attempting to login via email/social.

I have a usecase wherein I need to follow separate modes of migration for both login by email and login by social idps (google, facebook).
Hence I’m looking into how can getUserByEmail distinguish between the two.

When a user logs in via an external IdP (e.g. a social provider), there are 2 values set in the user session notes.

After a user login from an external IDP, Keycloak stores user session note data that you can access. This data can be propagated to the client requesting log in using the token or SAML assertion passed back to the client using an appropriate client mapper.

identity_provider
The IDP alias of the broker used to perform the login.

identity_provider_identity
The IDP username of the currently authenticated user. Often, but not always, the same as the Keycloak username. For example, Keycloak can link a user john` to a Facebook user john123@gmail.com. In that case, the value of the user session note is john123@gmail.com.

They are documented here: Server Administration Guide

@xgp Thank you for the response,

I think the session notes are setup after the user is created. What I’m looking for is more so right before the user gets created.

In my User Storage SPI, I am trying to migrate a user from external storage to keycloak and it’s being handled in getUserByEmail. But before migration in getUserByEmail is invoked, I want to check if the user trying to login is logging in via email or via social. Because for both email and social flows getUserByEmail is invoked.

I’m answering to this question here and to the topic Social Login not working as expected with User Storage SPI as it seems to be the same question from the same OP.

In fact, you shouldn’t distinguish in a UserStorageProvider the type of authentication. Keycloak uses SoC (separation of concerns) with the SPIs and the UserStorageProvider is just for managing the storage (read/write) of users, no matter where the request originates from.

If Keycloak finds a user in the internal DB, from my experience, the getUserByEmail() method of a storage provider is not called, as there is already a user. Only if there is no user found in the internal DB, Keycloak iterates through all configured storage providers sequentially(!!) and tries to find the user.

If you still want to distinguish in the storage provider something (but IMHO you don’t need it, if everything else, e.g. authentication flows, etc., is properly configured), see what the KeycloakSession and the Context (from keycloakSession.getContext() will give you. If there’s an AuthenticationSession, see what the auth notes, client session notes and user session notes have been stored.