拦截用户请求,通过请求头中的token,获取用户信息,并打开用户请求上下文。
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <p>
* 拦截请求打开用户上下文
*/
@Slf4j
public class UserAuthorizationInterceptor implements HandlerInterceptor {
@Autowired
private CacheService cacheService;
@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception {
//用户登录成功后就会打开SecurityContext,类似于我们即将打开的用户请求上下文
final SecurityContext securityContext = SecurityContextHolder.getContext();
//从SecurityContext获取安全认证信息
final Authentication authentication = securityContext.getAuthentication();
if (authentication != null) {
String accessToken;
if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
//如果安全认证信息不为空,并且是OAuth2AuthenticationDetails类型的,说明此请求已经通过了OAuth2的安全验证
final OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
accessToken = details.getTokenValue();
} else {
//如果还没通过OAuth2的安全认证,说明此请求是网关拦截器用以获取token对应的用户信息
final String authorization = request.getHeader("Authorization");
accessToken = authorization.replace("Bearer ", "");
}
if (StringUtils.isNotEmpty(accessToken)) {
if (cacheService.exists(RedisFolderName.REDIS_FOLDER_ACCESS_TOKEN_USER + accessToken)) {
final User currentUser = cacheService.get(RedisFolderName.REDIS_FOLDER_ACCESS_TOKEN_USER + accessToken, User.class);
if (currentUser != null) {
final String activeDomain = (String)
cacheService.get(RedisFolderName.REDIS_FOLDER_ACTIVE_DOMAIN + currentUser.getEmployeeNo());
//开启用户,ActiveDomain上下文环境
new UserContext(currentUser, activeDomain);
return true;
}
}
}
}
log.warn("url:{}, 访问请求中缺少access_token信息,未注册User Context", request.getRequestURL());
return true;
}
@Override
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) throws Exception {
UserContext.close(); //退出用户的上下文环境
}
}