一、在pom.xml中导入SpringCloudGateway jar包
XML
dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
二、在application.yaml中配置接口路径
java
url-auth:
whitelist:
- /demo/login
- /demo/captcha
三、属性配置类
java
@Data
@Configuration
@ConfigurationProperties(prefix = "url-auth")
public class UrlAuthProperties {
/***白名单,不做鉴权处理,只做简单的业务处理*/
private List<String> whitelist=new ArrayList<>();
/**
* 黑名单
*/
private List<String> blacklist = new ArrayList<>();
/**
* 忽略名单,不做任何处理
*/
private List<String> ignoreList = new ArrayList<>();
}
四、封装基础拦截器
java
/**
* 基础拦截器
*
*/
@Slf4j
public abstract class BaseFilter implements GlobalFilter, Ordered {
@Autowired
private UrlAuthProperties urlAuthProperties;
/**
* 白名单校验
*/
public boolean isWhitelist(ServerHttpRequest request) {
boolean result = false;
String path = request.getPath().toString();
HttpMethod httpMethod = request.getMethod();
if (httpMethod != null && httpMethod.name().equals(HttpMethod.OPTIONS.name())) {
result = true;
} else if (StringUtils.isNotBlank(path)) {
List<String> urls = urlAuthProperties.getWhitelist();
result = matchUrl(urls,path);
}
if(result == true) {
log.info("path:{}, whitelist:{}", path, result);
}
return result;
}
/**
* antPathMatcher.match("/user/*", "/user/a");
* antPathMatcher.match("/user/**", "/user/a/b");
* antPathMatcher.match("/user/name", "/user/a");
* antPathMatcher.isPattern("user/{id}");
* @param urls
* @param path
* @return
*/
private Boolean matchUrl(List<String> urls,String path) {
AntPathMatcher antPathMatcher = new AntPathMatcher();
for (Iterator<String> iterator = urls.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
if(string.equals(path) || antPathMatcher.match(string, path)) {
return true;
}
}
return false;
}
/**
* 忽略列表处理
*/
public boolean isIgnoreList(ServerHttpRequest request) {
boolean result = false;
String path = request.getPath().toString();
HttpMethod httpMethod = request.getMethod();
if (httpMethod != null && httpMethod.name().equals(HttpMethod.OPTIONS.name())) {
result = true;
} else if (StringUtils.isNotBlank(path)) {
List<String> urls = urlAuthProperties.getIgnoreList();
return urls.contains(path);
}
log.debug("path:{}, IgnoreList:{}", path, result);
return result;
}
/**
* 黑名单校验
* 在黑名单中的请求链接将返回true
*/
public boolean isBlacklist(ServerHttpRequest request) {
boolean result = false;
String path = request.getPath().toString();
HttpMethod httpMethod = request.getMethod();
if (httpMethod != null && httpMethod.name().equals(HttpMethod.OPTIONS.name())) {
result = true;
} else if (StringUtils.isNotBlank(path)) {
List<String> urls = urlAuthProperties.getBlacklist();
return urls.contains(path);
}
log.debug("path:{},blacklist:{}", path, result);
return result;
}
/***从当前请求(请求头/cookie)获取授权参数*/
public String getFromHeaderAndCookie(ServerHttpRequest request, String key) {
HttpHeaders headers = request.getHeaders();
// 1.从请求头中获取
String paramValue = headers.getFirst(key);
if (StrUtil.isBlank(paramValue)) {
// 2.从cookie中获取
MultiValueMap<String, HttpCookie> cookies = request.getCookies();
HttpCookie cookie = cookies.getFirst(key);
paramValue = Optional.ofNullable(cookie).map(HttpCookie::getValue).orElse(null);
}
return paramValue;
}
}
五、实际接口拦截入口
java
@Slf4j
@Component
public class SecurityFilter extends BaseFilter {
private static final String AUTHORIZATION = "Authorization";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 白名单直接放行不做token校验
if (isWhitelist(request)) {
return chain.filter(exchange);
}
String authorization = getFromHeaderAndCookie(request, AUTHORIZATION);
if (StringUtils.isBlank(authorization) || JwtUtils.isExpire(authorization)) {
throw new BusinessException(CommonErrorEnum.UNAUTHORIZED);
}
LoginContext loginContext = JwtUtils.getCurrentUser(authorization);
loginContext.setClientType(ClientType.ADMIN);
LoginContextHolder.set(loginContext);
String text = JSON.toJSONString(loginContext);
log.info("LoginContext:{}", text);
String unicode = UnicodeUtil.toUnicode(text, true);
String[] headerValues = new String[]{unicode};
ServerHttpRequest newRequest = exchange.getRequest().mutate()
.header(LoginContextConst.LOGIN_USER, headerValues)
.header(LoginContextConst.TOKEN, authorization).build();
//构建新的ServerWebExchange实例
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
}
@Override
public int getOrder() {
return 0;
}
}