前提:先保证Gateway网关项目 和 Nacos注册中心 等可以正常访问和调用,搭建方法可查看博文
SpringCloud Gateway网关 项目创建 及 整合Nacos开发_spring gateway如何设置工程名称-CSDN博客
业务流程
1 nacos配置中心,白名单设置
# 安全配置
security:
# 不校验白名单
ignore:
whites:
- /auth/login
2 白名单配置类
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
/**
* 放行白名单配置
*
* @author ruoyi
*/
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.ignore")
public class IgnoreWhiteProperties
{
/**
* 放行白名单配置,网关不校验此处的白名单
*/
private List<String> whites = new ArrayList<>();
public List<String> getWhites()
{
return whites;
}
public void setWhites(List<String> whites)
{
this.whites = whites;
}
}
3 核心代码,网关过滤器
package cn.huawei.filter;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class UserGlobalFilter implements GlobalFilter, Ordered {
@Autowired
private IgnoreWhiteProperties ignoreWhiteProperties;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest serverHttpRequest = exchange.getRequest();
String path = serverHttpRequest.getURI().getPath();
String token = serverHttpRequest.getHeaders().getFirst("token");
//不需要认证的路径,直接放行
List<String> whites = ignoreWhiteProperties.getWhites();
if (whites.contains(path)) {
return chain.filter(exchange);
}
if(StringUtils.isBlank(token))
{
//写法1
//设置状态码 未授权401
//exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//个人理解,终止输出访问
//return exchange.getResponse().setComplete();
//写法2
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
response.setStatusCode(HttpStatus.FORBIDDEN);
DataBufferFactory dataBufferFactory = response.bufferFactory();
DataBuffer dataBuffer = dataBufferFactory.wrap("无权限".getBytes(StandardCharsets.UTF_8));
return response.writeWith(Mono.just(dataBuffer));
}
//继续往下执行
return chain.filter(exchange);
}
/*
数字越小,优先级越高
*/
@Override
public int getOrder() {
return 0;
}
}
测试
通过网关访问的时候,header中需要添加token,否则不可以访问
1.代码解释
我们要在项目中实现一个拦截器,需要继承两个类:GlobalFilter, Ordered
GlobalFilter:全局过滤拦截器,在gateway中已经有部分实现
Ordered:拦截器的顺序
2.简介
我们在使用Spring Cloud Gateway的时候,注意到过滤器(包括GatewayFilter、GlobalFilter和过滤器链GatewayFilterChain),都依赖到ServerWebExchange。
这里的设计和Servlet中的Filter是相似的,当前过滤器可以决定是否执行下一个过滤器的逻辑,由GatewayFilterChain#filter()是否被调用来决定。而ServerWebExchange就相当于当前请求和响应的上下文。
ServerWebExchange实例不单存储了Request和Response对象,还提供了一些扩展方法,如果想实现改造请求参数或者响应参数,就必须深入了解ServerWebExchange。
3.ServerWebExchange
ServerWebExchange的注释: ServerWebExchange是一个HTTP请求-响应交互的契约。提供对HTTP请求和响应的访问,并公开额外的服务器端处理相关属性和特性,如请求属性。
其实,ServerWebExchange命名为服务网络交换器,存放着重要的请求-响应属性、请求实例和响应实例等等,有点像Context的角色。