Custom UserStorageProvider in Keycloak 18.0.0

Hi there,

I’ve created a basic User Storage Provider and am currently trying to understand how adding new users works.

So far, I understand it like this:

  • the overridden addUser(final RealmModel realmModel, final String s) method will be invoked whenever a user is being added from Keycloak’s side. Correct?
  • under assumption the above is correct:
    ** if we had multiple custom providers, how can we differentiate within method between those providers and decide in which one the user should be created?
    ** the s parameter is the username. Is there a way in this method to get an access to values of ALL fields filled in Keycloak console, not only the username?

@dasniko I’d really appreciate if you could give some input here. Let me know if you’d rather not to be tagged like this in the future and apologies in advance for doing that this time.

the overridden addUser(final RealmModel realmModel, final String s) method will be invoked whenever a user is being added from Keycloak’s side. Correct?

Yes, that’s correct. Here you can decide, if the user should be added to your storage provider or not. Returning null means no, I don’t want to add this user to this provider.
Returning an instance of UserModel means yes, I want to add this user to this provider.

Keycloak will then populate your custom UserModel instance with proper attributes. So, best practice is to provide a custom class which implements UserModel or extends one of the AbstractUserAdapter…classes. In theaddUser` method you only have access to the objects provided through the method arguments (realm and username). You’ll have to build your decision around these values.

1 Like

Generally, for the future, don’t tag people directly, unless really needed/requested. It’s in the nature of a public forum that the people which are able to help, will help you, if you formulate the question properly enough.

2 Likes

Thank you for your reply!
So the quoted excerpt means that if one wants to create a user, they can only set the username, even though the form in the Keycloak Admin Console had other fields? Wouldn’t a map containing all the fields and their values be a better choice for this param instead of a username string. I suppose the read-only nature was considered here but really, allowing only a username to be set on a new user doesn’t make much sense.

No, in the method you only have the username to decide and create an UserModel instance. As I wrote, if this method returns an UserModel object, Keycloak will populate this object with the entered values. You just can’t access all the values in the addUser method, it will be done afterwards.
That’s how it is, I don’t like it either, but I can’t change it. :man_shrugging:

Thanks for the last reply, I only got time today to give it a try.

You said:

“in the method you only have the username to decide and create an UserModel instance”
Got that, I could use it to eg. query my custom storage to check if the user already exists and if so, return null to signal I don’t want this user to be added.

" if this method returns an UserModel object, Keycloak will populate this object with the entered values."
My custom storage is RESTful so it would make sense to call my API somewhere in order to POST the new Account object to be created? Obviously I can’t do it in the addUser() method (where it would actually make most sense) because a) I don’t have access to attributes and b) as you said, the UserModel object that I should return will only be later populated.