定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiHeaderCheck {
}
定义切面
@Aspect
@Component
@Slf4j
public class ApiHeaderCheckAspect {
//30s超时
public static final int REQUEST_EXPIRE_TIME = 30000;
@Before("@annotation(apiHeaderCheck)")
public void checkAuth(ApiHeaderCheck apiHeaderCheck) {
HttpServletRequest request = currentRequest();
if (Objects.isNull(request)) {
return;
}
String timeStampStr = request.getHeader("x-ts");
String sign = request.getHeader("x-sign");
if (StringUtils.isEmpty(timeStampStr) || StringUtils.isEmpty(sign)) {
throw new BaseException(ApiAuthErrorEnum.UNAUTHORIZED);
}
String regex = "^\d{13}$";
if (!Pattern.matches(regex, timeStampStr.trim())) {
throw new BaseException(ApiAuthErrorEnum.UNAUTHORIZED);
}
long requestTimestamp = Long.parseLong(timeStampStr);
if (System.currentTimeMillis() - requestTimestamp > REQUEST_EXPIRE_TIME) {
throw new BaseException(ApiAuthErrorEnum.REQUEST_EXPIRED);
}
//验证RSA签名
String targetTimestamp = RsaUtil.decrypt(sign);
if (!targetTimestamp.equals(timeStampStr)) {
throw new BaseException(ApiAuthErrorEnum.UNAUTHORIZED);
}
}
/**
* 获取当前请求信息
* @return Current request or null
*/
private HttpServletRequest currentRequest() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return Optional.ofNullable(servletRequestAttributes).map(ServletRequestAttributes::getRequest).orElse(null);
}
}
定义异常
1 public enum ApiAuthErrorEnum implements IErrorCode { 2 3 UNAUTHORIZED("10001", "Unauthorized"), 4 REQUEST_EXPIRED("10002", "Request Expired"), 5 ; 6 7 private final String errorCode; 8 private final String errorMessage; 9 private static final String ERROR_CODE_START = "Auth-"; 10 11 ApiAuthErrorEnum(String errorCode, String errorMessage) { 12 this.errorCode = errorCode; 13 this.errorMessage = errorMessage; 14 } 15 16 @Override 17 public String getErrorCode() { 18 return ERROR_CODE_START + errorCode; 19 } 20 21 @Override 22 public String getErrorMessage() { 23 return errorMessage; 24 } 25 }
使用方式
在方法上添加@ApiHeaderCheck
Nginx.conf对应路径增加
add_header Access-Control-Allow-Headers 'x-sign,x-ts'; 如
location /bssgw/ {
proxy_pass http://127.0.0.1:8080/test/;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Headers 'x-sign,x-ts';
client_max_body_size 50m;
}