com.github.dennisit.vplus.data.security.token.JwtTokenAuthInterceptor Maven / Gradle / Ivy
package com.github.dennisit.vplus.data.security.token;
import com.alibaba.fastjson.JSON;
import com.github.dennisit.vplus.data.result.AInstatus;
import com.github.dennisit.vplus.data.result.ApiResult;
import com.github.dennisit.vplus.data.security.AuthorityIFace;
import com.github.dennisit.vplus.data.security.AuthorityUtils;
import com.spring.boxes.dollar.term.Authority;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Optional;
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class JwtTokenAuthInterceptor implements HandlerInterceptor {
private String TOKEN_KEY = "ticket";
private String SECRET_KEY = "com.spring.boxes";
private AuthorityIFace authorityIface;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
if (request.getMethod().equalsIgnoreCase(RequestMethod.OPTIONS.name())) {
response.setStatus(HttpStatus.OK.value());
return true;
}
try {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
if (method.isAnnotationPresent(JwtAuthentication.class)) {
String token = getRequestToken(request);
if (StringUtils.isBlank(token)) {
reject(request, response);
return false;
}
Map map = JwtToken.parser(token, SECRET_KEY);
long userId = MapUtils.getLongValue(map, JwtToken.Fields.USER_ID);
String providerId = MapUtils.getString(map, JwtToken.Fields.PROVIDER_ID);
String providerUserId = MapUtils.getString(map, JwtToken.Fields.PROVIDER_USER_ID);
log.info("[JWT] userId:{}, providerId:{}, providerUserId:{}", userId, providerId, providerUserId);
// 根据平台用户名ID查询
Authority authority = authorityIface.selectByUserId(userId);
// 根据三方OpenId查询
if (null == authority) {
authority = authorityIface.selectByProviderUerId(providerUserId);
}
// 找不到用户无权限
if (null == authority) {
reject(request, response);
return false;
}
AuthorityUtils.setAuthority(authority);
}
} catch (Exception e) {
log.error(e.getLocalizedMessage(), e);
reject(request, response);
return false;
}
return true;
}
private void reject(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = response.getWriter();
out.write(JSON.toJSONString(ApiResult.failure(AInstatus.WuInstatus.UNAUTHORIZED)));
out.close();
}
private String getRequestToken(HttpServletRequest httpRequest) {
String token = Optional.ofNullable(WebUtils.getCookie(httpRequest, TOKEN_KEY)).map(x -> x.getValue()).orElse(StringUtils.EMPTY);
if (StringUtils.isBlank(token)) {
token = httpRequest.getHeader(TOKEN_KEY);
}
if (StringUtils.isBlank(token)) {
token = httpRequest.getParameter(TOKEN_KEY);
}
return token;
}
}