SSO登出方案:MQ+双黑名单

系统架构设计

1. 管理黑名单
2. 发布事件
3. 推送事件
3. 推送事件
3. 推送事件
4. 同步
4. 同步
4. 同步
SSO Server
Redis全局黑名单
RabbitMQ
业务系统1
业务系统2
业务系统N
本地黑名单
本地黑名单
本地黑名单

核心组件说明

  1. 全局黑名单:Redis 存储,记录所有注销的 Token

    • 数据结构:SET 类型,Key: global_blacklist
    • TTL 自动过期(与 Token 有效期一致)
  2. 本地黑名单:业务系统内存缓存(Caffeine)

    • 自动过期机制(略短于Token有效期)
    • 定期同步全局黑名单(5min)
  3. RabbitMQ:消息通知通道

    • Exchange:sso_events (Fanout 类型)
    • Queue:每个业务系统独立队列
    • 消息格式:JSON {eventType, token, timestamp}

登出流程设计

UserBusinessAppSSOServerRedisRabbitMQOtherSystems请求登出发送登出请求(token)添加到全局黑名单发布黑名单事件推送事件推送事件更新本地黑名单更新本地黑名单loop[所有系统]返回登出成功清除会话UserBusinessAppSSOServerRedisRabbitMQOtherSystems

关键代码实现

// 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);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值