如何通过API接收Keycloak用户禁用通知?含相关场景补充
Keycloak用户禁用通知与暴力检测告警实现方案
完全可行,Keycloak提供了完善的事件监听机制来实现用户状态变更通知与暴力登录检测告警,以下是具体实现方案和代码示例:
一、核心实现思路
通过Keycloak的**事件监听(Event Listener)**功能,捕获USER_DISABLED(用户禁用)、LOGIN_FAILURE(登录失败)等关键事件,再将事件数据推送到你的业务服务接口。
二、快速实现:使用Webhook扩展
社区维护的keycloak-webhook-event-listener扩展可快速实现事件推送,无需编码:
- 下载对应Keycloak版本的扩展JAR包,放入Keycloak部署目录的
standalone/deployments文件夹 - 重启Keycloak后,进入目标Realm的Events配置页:
- 在Event Listeners列表中添加
webhook监听器 - 点击Webhook Settings,配置你的服务接收地址(如
http://your-service.com/webhook/keycloak) - 勾选需要监听的事件类型:
USER_DISABLED、LOGIN_FAILURE、USER_LOCKED等
- 在Event Listeners列表中添加
- 保存配置后,Keycloak会自动将对应事件推送到你的服务
三、自定义监听器(灵活适配业务)
如果需要自定义事件处理逻辑,可编写Java监听器:
import org.keycloak.events.Event; import org.keycloak.events.EventListenerProvider; import org.keycloak.events.EventType; import org.keycloak.models.KeycloakSession; import java.util.Arrays; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; public class CustomEventNotifier implements EventListenerProvider { private final KeycloakSession session; private final OkHttpClient httpClient = new OkHttpClient(); private static final String YOUR_SERVICE_URL = "http://your-service.com/webhook/keycloak"; public CustomEventNotifier(KeycloakSession session) { this.session = session; } @Override public void onEvent(Event event) { // 处理用户禁用事件 if (EventType.USER_DISABLED.equals(event.getType())) { String username = session.users().getUserById(session.getContext().getRealm(), event.getUserId()).getUsername(); sendEventToService("USER_DISABLED", username, event.getUserId()); } // 处理登录失败(暴力检测)事件 if (EventType.LOGIN_FAILURE.equals(event.getType())) { String username = event.getDetails().get("username"); String ip = event.getIpAddress(); sendEventToService("LOGIN_FAILURE", username, ip); } } private void sendEventToService(String eventType, String... details) { String payload = String.format( "{\"eventType\":\"%s\",\"details\":%s}", eventType, Arrays.toString(details) ); RequestBody body = RequestBody.create( payload, MediaType.parse("application/json") ); Request request = new Request.Builder() .url(YOUR_SERVICE_URL) .post(body) .build(); // 异步发送请求,避免阻塞Keycloak httpClient.newCall(request).enqueue(null); } @Override public void close() {} }
按照Keycloak扩展规范打包部署后,在Realm的Event Listeners中添加自定义监听器即可。
四、业务服务接收示例(Spring Boot)
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/webhook") public class KeycloakEventController { @PostMapping("/keycloak") public void handleKeycloakEvent(@RequestBody KeycloakEvent event) { switch (event.getEventType()) { case "USER_DISABLED": // 执行用户禁用后的业务逻辑:同步状态、内部告警等 System.out.printf("用户【%s】已被禁用,ID:%s%n", event.getDetails()[0], event.getDetails()[1]); break; case "LOGIN_FAILURE": // 处理暴力登录告警:记录日志、触发短信通知等 System.out.printf("用户【%s】登录失败,IP:%s%n", event.getDetails()[0], event.getDetails()[1]); break; default: // 其他事件处理 break; } } static class KeycloakEvent { private String eventType; private String[] details; // getter/setter } }
五、暴力检测配置
在Keycloak控制台进入目标Realm → Security Defenses → Brute Force Detection:
- 启用暴力检测,配置允许的失败登录次数、账户锁定时长等参数
- 当达到阈值时,Keycloak会触发
USER_LOCKED事件,可通过上述监听器推送告警
相关配置与事件截图
- 暴力检测基础配置界面:

- 暴力检测阈值设置界面:

- 我方服务接收的事件记录界面:

内容的提问来源于stack exchange,提问作者Самир Шахмурадлы
相关产品推荐
相关产品推荐

