接口权限拦截器
import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.security.Key;
import java.util.List;
import java.util.Map;
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {
public static final String jwtSecret = "ABCDEFGHIJKLMNOPQRSTUVMXYZABCDEFGHIJKLMNOPQRSTUVMXYZABCDEFGHIJKLMNOPQRSTUVMXYZABCDEFGHIJKLMNOPQRSTUVMXYZ";
public static final String BASIC_TOKEN_PREFIX = "Basic ";
public static final String NUC_COOKIE_NAME = "_a";
public static final String HEADER = "UserInfo";
public static final String HEAD_TOKEN = "Authorization";
@Autowired
AppService appService;
protected Claims checkToken(HttpServletRequest req) {
String[] headers = {HEADER, HEAD_TOKEN};
String tokenString = getTokenString(req, headers, NUC_COOKIE_NAME);
log.info("tokenString:" + tokenString);
if (StringUtils.isNotEmpty(tokenString)) {
return decryptJwtToken(tokenString);
}
return null;
}
public static String getTokenString(HttpServletRequest req, String[] headerKeys, String cookieName) {
for (String header : headerKeys) {
String tokenString = req.getHeader(header);
if (!StringUtils.isEmpty(tokenString)) {
return tokenString;
}
}
Cookie tokenCookie = getCookieByName(req, cookieName);
if (tokenCookie != null) {
return tokenCookie.getValue();
}
return null;
}
public static Cookie getCookieByName(HttpServletRequest req, String cookieName) {
if (req.getCookies() != null) {
Cookie[] var3 = req.getCookies();
int var4 = var3.length;
for (int var5 = 0; var5 < var4; ++var5) {
Cookie cookie = var3[var5];
if (StringUtils.equals(cookieName, cookie.getName())) {
return cookie;
}
}
}
return null;
}
public Claims decryptJwtToken(String jwt) {
try {
Claims claims = Jwts.parser()
.setSigningKey(generateKey())
.parseClaimsJws(jwt.substring(BASIC_TOKEN_PREFIX.length())).getBody();
return claims;
} catch (Exception e) {
return null;
}
}
private Key generateKey() {
Key signingKey = new SecretKeySpec(jwtSecret.getBytes(), SignatureAlgorithm.HS512.getJcaName());
return signingKey;
}
private boolean localCheckToken(HttpServletRequest request, Object object) {
String token = request.getHeader("Token");
log.info("Token串:" + token);
if (!(object instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) object;
Method method = handlerMethod.getMethod();
if (method.isAnnotationPresent(LoginToken.class)) {
LoginToken loginToken = method.getAnnotation(LoginToken.class);
if (loginToken.required()) {
return true;
}
}
if (method.isAnnotationPresent(CheckToken.class)) {
CheckToken checkToken = method.getAnnotation(CheckToken.class);
if (checkToken.required()) {
if (token == null) {
throw new RuntimeException("无token,请重新获取!");
}
String appId;
try {
appId = JWT.decode(token).getClaim("appId").asString();
} catch (JWTDecodeException j) {
throw new RuntimeException("token解析异常");
}
AppQuery appQuery = new AppQuery();
appQuery.setAppId(appId);
PageBean<AppVO> pageBean = appService.queryApp(appQuery);
if (pageBean.getList() == null || pageBean.getList().size() == 0 || appId == null) {
throw new RuntimeException("应用不存在,请先申请!");
}
Boolean verify = JwtUtil.isVerify(token, pageBean.getList().get(0));
if (!verify) {
throw new RuntimeException("非法访问!");
}
return true;
}
}
return true;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return localCheckToken(request, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
@Test
public void test() {
String jwt = "5001062a21696331e6ad87e6f2f7a76db744a1239c86350038f266166728b86a11aa6c70d794c738745d012062912ff93d47";
decryptJwtToken(jwt);
}
}
jwt生成token工具类
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class JwtUtil {
public static String createJWT(long ttlMillis, AppVO app) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("appId", app.getAppId());
claims.put("appKey", app.getAppKey());
claims.put("appSecret", app.getAppSecret());
String key = app.getAppSecret();
String subject = app.getAppKey();
JwtBuilder builder = Jwts.builder()
.setClaims(claims)
.setId(UUID.randomUUID().toString())
.setIssuedAt(now)
.setSubject(subject)
.signWith(signatureAlgorithm, key);
if (ttlMillis >= 0) {
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp);
}
return builder.compact();
}
public static Claims parseJWT(String token, AppQuery app) {
String key = app.getAppSecret();
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token).getBody();
return claims;
}
public static Boolean isVerify(String token, AppVO app) {
String key = app.getAppSecret();
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token).getBody();
if (claims.get("appSecret").equals(app.getAppSecret())) {
return true;
}
return false;
}
}
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
## 查询应用Bean
@Data
@ApiModel
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown=true)
public class AppQuery {
@ApiModelProperty(value = "应用ID")
private String appId;
@ApiModelProperty(value = "应用key")
private String appKey;
@ApiModelProperty(value = "应用秘钥")
private String appSecret;
@ApiModelProperty(value = "系统标识")
private String systemKey;
@ApiModelProperty(value = "系统名称")
private String systemName;
}
应用返回的bean
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel
public class AppVO {
@ApiModelProperty(value = "应用Id")
private String appId;
@ApiModelProperty(value = "应用账号")
private String appKey;
@ApiModelProperty(value = "应用秘钥")
private String appSecret;
@ApiModelProperty(value = "系统标识")
private String systemKey;
@ApiModelProperty(value = "系统名称")
private String systemName;
@ApiModelProperty(value = "创建人")
private String createdUser;
@ApiModelProperty(value = "更新人")
private String updatedUser;
@ApiModelProperty(value = "创建日期")
private String createdDate;
@ApiModelProperty(value = "更新日期")
private String updatedDate;
@ApiModelProperty(value = "是否有效")
private String isValid;
}
接口权限注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckToken {
boolean required() default true;
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginToken {
boolean required() default true;
}
Controller
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jra.Put;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Api(tags = "提供业务系统接口")
@RestController
@RequestMapping({"/api/v1/"})
public class ExternalController {
private Logger logger = LoggerFactory.getLogger(ExternalController.class);
@ApiOperation("获取token")
@PostMapping(value = "getToken")
public WebResponse token(@RequestBody AppQuery app) {
AppVO appVO = appService.queryAppByAppKey(app);
if (appVO == null) {
return WebResponse.buildFail("appKey或appSecret校验不通过!");
}
String token = JwtUtil.createJWT(900000, appVO);
return WebResponse.buildSuccess(token, "获取token成功!");
}
@ApiOperation("查询用户")
@PostMapping(value = "users", consumes = {"application/json"})
@CheckToken
public WebResponse getUserList(
@RequestBody @Validated WebRequest<UserRequestDTO> body) {
return new WebResponse(thirdService.getUserList(body.getBody()));
}
}