背景:
我在实现sso登录请求的时候设计了两个接口分别是 sso/token和sso/login
这两个请求没有添加到TenantInterceptor租户拦截器的放行接口列表中
以下是TenantInterceptor代码:
public class TenantInterceptor implements AsyncHandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler)
throws Exception {
boolean isPass = false;
Cookie[] cookies = request.getCookies();
Opt<String> token = Opt.empty();
if (Asserts.isNotNull(cookies)) {
for (Cookie cookie : cookies) {
switch (cookie.getName()) {
case "token":
token = Opt.ofBlankAble(cookie.getValue());
SaTokenDao saTokenDao = SaManager.getSaTokenDao();
String keyTokenValue = StpUtil.getStpLogic().splicingKeyTokenValue(token.get());
if (saTokenDao.get(keyTokenValue) != null) {
isPass = true;
}
break;
case "tenantId":
if (!StpUtil.isLogin()) {
return false;
}
UserDTO userInfo = UserInfoContextHolder.get(StpUtil.getLoginIdAsInt());
if (Asserts.isNull(userInfo)) {
StpUtil.logout(StpUtil.getLoginIdAsInt());
return false;
}
int finalTenantId = Integer.parseInt(cookie.getValue());
List<Tenant> tenants =
Opt.ofNullable(userInfo.getTenantList()).orElse(new ArrayList<>()).stream()
.filter(t -> t.getId() == finalTenantId)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(tenants)) {
StpUtil.logout(StpUtil.getLoginIdAsInt());
return false;
}
TenantContextHolder.set(finalTenantId);
break;
}
}
}
return AsyncHandlerInterceptor.super.preHandle(request, response, handler);
}
}
可以看到没有一个日志信息,这导致了我请求sso/token和sso/login接口 能够正常返回200到没有数据(因为被拦截)
debug:
将日志调为debug模式 找到
org.springframework.web.servlet.FrameworkServlet类的processRequest方法中的doService打上断点排查一步一步执行下来发现 org. springframework. web. servlet. DispatcherServlet的doDispatch方法中
//这一行循环了拦截器看看会被哪个拦截器拦截
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//这一行循环了拦截器看看会被哪个拦截器拦截
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
这里如果被拦截了 会直接返回不走接口的方法了,而且没日志报错的这是重点,所以你也不知道会被哪个拦截器拦截。。。。建议拦截器里加点日志方便排查