SpringCloud:Gateway网关中自定义过滤器
目的实现自定义的过滤规则,如token校验,权限校验等。方法实现GlobalFilter和Ordered。GlobalFilter:公共过滤器Ordered:过滤优先级,根据处理顺序修改大小。自定义过滤器import com.gateway.code.ResponseCode;import com.gateway.core.utils.PathUtil;import...
·
目的
实现自定义的过滤规则,如token校验,权限校验等。
方法
实现GlobalFilter和Ordered。
GlobalFilter:公共过滤器
Ordered:过滤优先级,根据处理顺序修改大小。
- 自定义过滤器
import com.gateway.code.ResponseCode;
import com.gateway.core.utils.PathUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
/**
* 访问权限校验
* 通过验证jwt判断是否可以多路径进行访问
*
* @author: lizz
* @date: 2020/1/20 9:46
*/
@Component
public class AuthFilter implements GlobalFilter, Ordered {
private static final Logger logger = LoggerFactory.getLogger(AuthFilter.class);
/**
* 需要忽略auth校验的路径匹配集合
*/
@Value("${auth.ignore}")
private List<String> authIgnore;
/**
* 需要进行auth校验的路径匹配集合
*/
@Value("${auth.rules}")
private List<String> authRules;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
if (PathUtil.checkPath(request.getPath().value(),authRules,authIgnore)) {
//get访问通过
//其他访问方式返回401
if(request.getMethod() == HttpMethod.GET){
logger.info("fgwCheckAuth success:id={}", request.getId());
return chain.filter(exchange);
}else{
logger.info("fgwCheckAuth failed:id={}", request.getId());
return buildReqsponse(exchange.getResponse(), HttpStatus.UNAUTHORIZED,
ResponseCode.UNAUTH);
}
}else {
//无需校验,直接返回
return chain.filter(exchange);
}
}
/**
* 自定义返回结果
* @param response
* @param httpStatus
* @param code
* @return
*/
public static Mono<Void> buildReqsponse(ServerHttpResponse response, HttpStatus httpStatus, ResponseCode code) {
response.setStatusCode(httpStatus);
HttpHeaders httpHeaders = response.getHeaders();
httpHeaders.add("sever", "fw-gw");
httpHeaders.add("Content-Type", "application/json; charset=UTF-8");
httpHeaders.add("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
String returnMsg = code.toString();
DataBuffer bodyDataBuffer = response.bufferFactory().wrap(returnMsg.getBytes());
return response.writeWith(Mono.just(bodyDataBuffer));
}
@Override
public int getOrder() {
//拦截器优先级,越小位最先执行
return -179;
}
}
- PathUtil
import java.nio.file.FileSystems;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.util.List;
/**
* 路径操作工具类
*
* @author: lizz
* @date: 2020/1/9 11:17
*/
public class PathUtil {
/**
* 获取路径分段值
* @param path 完整路径
* @param num 第几分段
* @return
*/
public static String segment(String path, int num) {
return path.split("/")[num];
}
/**
* 路径分段中是否存在某个字符串
* @param path 路径
* @param key 匹配的字符串
* @return
*/
public static boolean exist(String path, String key) {
String[] paths = path.split("/");
for (String p : paths) {
if (p.equals(key)) {
return true;
}
}
return false;
}
/**
* 多规则匹配
*
* @param rules 规则集合
* @param path 路径
* @return
*/
public static boolean matches(List<String> rules, String path) {
for(String rule : rules){
if (matches(rule, path)) {
return true;
}
}
return false;
}
/**
* 路径匹配
*
* @param rule 规则
* @param path 路径
* @return
*/
public static boolean matches(String rule, String path) {
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + rule);
return matcher.matches(Paths.get(path));
}
/**
* 过滤路径
* @param path
* @param rules
* @param ignoreRules
* @return
*/
public static boolean checkPath(String path, List<String> rules,List<String> ignoreRules) {
//是否匹配过滤路径
if (rules.size() > 0 && PathUtil.matches(rules, path)) {
//匹配到需要校验的规则
//判断是否忽略
if (ignoreRules.size() > 0
&& PathUtil.matches(ignoreRules, path)) {
//忽略路径
return false;
} else {
//需要校验
return true;
}
} else {
//没有需要校验的路径
return false;
}
}
}
- ResponseCode
package com.gateway.code;
/**
* 请求返回标准值
* @author: lizz
* @date: 2020/01/19 12:07
*/
public enum ResponseCode {
//请求成功
SUCCESS(0000, "请求成功"),
//请求失败
FAILED(1000, "请求失败"),
//用户不存在
NOT_USER(1001, "用户不存在"),
//非法请求token
ILLGAL(1002, "非法请求"),
//非法签名
ERROR_SIGN(1003, "非法签名"),
//无访问权限
UNAUTH(1004, "无权限");
private Integer code;
private String msg;
ResponseCode(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "{\"code\":" + this.code + ",\"msg\":\"" + this.msg + "\"}";
}
}
配置:
#忽略路径规则
auth.ignore = /hi/login,/hi/login/**
#验证路径规则
auth.rules = /hi/**,/bye/**
更多推荐



所有评论(0)