When there is an update to our current Terms and Conditions, I need a way to update all the Users to re-accept the Terms and Conditions. For this I don’t want to do this manually but use admin endpoint to update the User’s Required Actions to accept Terms and Conditions again. I’ve looked at the admin endpoint and we can do this for an individual User using PUT endpoint. But If we do this for multiple users, we’re calling the Keycloak’s endpoint multiple times and this can be very time consuming and inefficient.
Is there a bulk update REST endpoint for us to update multiple users all together? I don’t want to loop through the users and update individual user in my code. But I can’t seem to find bulk update endpoint and from multiple searches, actually this doesn’t exist and we have to either loop through it or update the Keycloak’s database.
Has anyone ran into this issue before? How did you solve this issue and can you please recommend the most efficient ways of updating multiple users instead of looping which will call Keycloak endpoint N(user) times?
There are no bulk update operations in the Admin REST API available. But you can extend the API with custom resources so that you can do with a custom endpoint and iterate internally over all users. This might be faster, but depending on the amount of users, you will have to deal with request timeouts.
@dasniko thanks for the reply! So basically we just create some separate PUT endpoint that will, within Keycloak, get all the users and add Required Actions to these available users? In this way, our apps will call Keycloak only once instead of the apps iterating users and making multiple request to Keycloak’s endpoint making it little more efficient?
If yes, I was looking at this post
Is some sort of sudo code like below a right approach in my custom endpoint?
// Fetch all users in the realm
List<UserModel> users = session.users().getUsers(realm);
// Add the required action to each user
for (UserModel user : users) {
user.addRequiredAction(UserModel.RequiredAction.TERMS_AND_CONDITIONS);
}
Thanks for the commit. I have couple of questions. I am running a Keycloak docker container to test this endpoint and so far everything seems to work well! But here are the questions:
What does below code do?
final UserPermissionEvaluator userPermissionEvaluator = auth.users();
userPermissionEvaluator.requireManage();
Reason I ask is I still do need access token to call the admin endpoint I extended, but I just didn’t get what you meant in the comment to bypass the authorization using above.
The access token seems to expire pretty quick, can I set token expiry time? and also how to access refresh token? For example, after I call the access token and use it from application, I can’t make subsequent calls, even though the lifespan seems 5 minutes?
What is the exact name of the action for each Required user action in the payload? For example in the code
payload.get("action"))
My application is sending something like
payload = {"action": "terms_and_conditions"}
but this doesn’t seem to correspond with the actual users required action. For example normally the text on the UI seems Terms and Conditions. Do I have to send the payload as the name it is or is it some sort of Enum? Just a bit confused from client side, what payload to send for Required user actions.
The above endpoint works and updates to what ever payload is given. However from the GUI when I try to remove the required action I added via custom endpoint, when I hit save, the required action I added persists there. What could I be doing wrong?
It checks if the current user, represented by the bearer token (access token), has the proper role (here: manage-users of client realm-management) to execute this method.
If you investigated the source code, you could have seen it.
I don’t bypass anything.
The easiest way to find this out, is to investigate the proper request when doing this in the admin ui. Simply open the developer console → network of your browser, assign a required action to a user, investigate the payload of the sent request.
Another way is to look into the source code of the respective required action and lookup the value the getId() method of the factory class returns.
In the case for t&c, the proper value is TERMS_AND_CONDITIONS.