/* * Copyright 2018-2020 by jason. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Vinay Sajip * not be used in advertising or publicity pertaining to distribution * of the software without specific, written prior permission. * VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL * VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ package cn.mb.cloud.auth.security.handler; import cn.mb.cloud.auth.security.component.MbCloudAuthUser; import cn.mb.cloud.auth.security.service.MbCloudUserAuthDetailsService; import cn.mb.cloud.auth.security.service.impl.MbCloudRedisTokenStore; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.event.AuthenticationSuccessEvent; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.stereotype.Component; import java.util.Collection; /** * @author: jason * @Date: 2019-05-17 17:20 * @Description: */ @Slf4j @Order(Ordered.HIGHEST_PRECEDENCE) @Component public class GlobalSuccessHandler implements ApplicationListener { private ThreadLocal lastEventHashCode = ThreadLocal.withInitial(() -> Integer.valueOf(0)); @Autowired private MbCloudUserAuthDetailsService userAuthDetailsService; @Autowired private MbCloudRedisTokenStore removeAccessToken; @Override public void onApplicationEvent(AuthenticationSuccessEvent event) { final int currentEventHashCode = event.hashCode(); log.info("监听到认证成功事件 ---> Last event hash code:{},current event hash code:{}", lastEventHashCode.get(), currentEventHashCode); Authentication authentication = event.getAuthentication(); Object principal = authentication.getPrincipal(); if (principal instanceof MbCloudAuthUser) { MbCloudAuthUser user = (MbCloudAuthUser)principal; Collection mbcloud = removeAccessToken.findTokensByClientIdAndUserName("mbcloud", user.getUsername()); mbcloud.stream().forEach(item->{ removeAccessToken.removeAccessToken(item.getValue()); }); MbCloudAuthUser authUser = (MbCloudAuthUser) principal; // 认证成功事件会触发两次,防止处理两次影响性能,所以判断Hash Code避免重复操作 if (lastEventHashCode.get().intValue() != currentEventHashCode) { userAuthDetailsService.loadUserPermissions(authUser.getId()); } } } }