系统架构设计
核心组件说明
-
全局黑名单:Redis 存储,记录所有注销的 Token
- 数据结构:
SET
类型,Key:global_blacklist
- TTL 自动过期(与 Token 有效期一致)
- 数据结构:
-
本地黑名单:业务系统内存缓存(Caffeine)
- 自动过期机制(略短于Token有效期)
- 定期同步全局黑名单(5min)
-
RabbitMQ:消息通知通道
- Exchange:
sso_events
(Fanout 类型) - Queue:每个业务系统独立队列
- 消息格式:JSON {eventType, token, timestamp}
- Exchange:
登出流程设计
关键代码实现:
// SSO Server 登出服务
@Service
public class LogoutService {
@Autowired private RabbitTemplate rabbitTemplate;
public void globalLogout(String token) {
// 1. 加入全局黑名单 (Redis SET)
redisTemplate.opsForSet().add("global_blacklist", token);
// 2. 设置自动过期 (与Token有效期一致)
redisTemplate.expire("global_blacklist", 30, MINUTES);
// 3. 发布MQ事件 [核心]
Map<String, Object> event = new HashMap<>();
event.put("eventType", "TOKEN_BLACKLISTED");
event.put("token", token);
event.put("timestamp", System.currentTimeMillis());
rabbitTemplate.convertAndSend("sso_events", "", event);
}
}
// 业务系统事件监听器
@Component
public class BlacklistEventListener {
@Autowired private LocalBlacklistCache localCache;
@RabbitListener(queues = "#{systemQueue}")
public void handleEvent(Map<String, Object> event) {
if ("TOKEN_BLACKLISTED".equals(event.get("eventType"))) {
String token = (String) event.get("token");
// 添加到本地黑名单缓存
localCache.addToBlacklist(token);
}
}
}
双黑名单验证机制
本地黑名单实现:
// 本地黑名单缓存,本地完成大部分失效Token验证 (Caffeine实现)
@Component
public class LocalBlacklistCache {
private final Cache<String, Boolean> cache = Caffeine.newBuilder()
.expireAfterWrite(30, MINUTES) // 自动过期
.build();
// 添加黑名单
public void addToBlacklist(String token) {
cache.put(token, true);
}
// 检查黑名单
public boolean isBlacklisted(String token) {
return cache.getIfPresent(token) != null;
}
// 定期同步全局黑名单 (每5分钟)
@Scheduled(fixedRate = 5 * 60 * 1000)
public void syncGlobalBlacklist() {
Set<String> globalList = ssoClient.getGlobalBlacklist();
globalList.forEach(this::addToBlacklist);
}
}