nacos网关自定义过滤器

package com.liron.filter;

import com.liron.system.SystemConstants;
import com.liron.utils.AppJwtUtil;
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.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 要先获取到用户发送过来的请求头才行
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //+ 2.判断当前的请求 是否 是登录的请求 如果是 ,则放行
        String path = request.getURI().getPath();
        if(path.equals("/x/login")){
            return chain.filter(exchange);
        }
        MultiValueMap<String, String> params = request.getHeaders();
        // 然后拿到请求头里面的token
        String token = params.getFirst("token");
        if(StringUtils.isEmpty(token)){
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return  response.setComplete();//完成响应 返回 后面就不执行了
        }
        // 校验token
        Integer verifyToken = AppJwtUtil.verifyToken(token);
        if (!verifyToken.equals(SystemConstants.JWT_OK)){
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // 放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        // put the filter first
        return 0;
    }
}
<think>好的,用户之前问过如何通过配置实现全局路由白名单,现在他想知道是否可以不使用自定义过滤器,而是用内置的GatewayFilterFactory来实现。首先,我需要确认用户的需求,他们可能希望避免编写代码,完全利用Spring Cloud Gateway的内置功能。 用户提到“不自定义过滤器”,所以需要回顾一下内置的过滤器工厂。之前回答中已经提到了使用RemoveRequestHeader来跳过认证头,但用户可能需要更全面的解决方案。需要检查是否有其他内置过滤器可以组合使用,比如StripPrefix、RewritePath,或者安全相关的过滤器,比如AddRequestHeader,但可能不够。 接下来,我需要考虑用户可能的场景。他们可能有多个白名单路径,需要绕过认证、鉴权等过滤器。内置过滤器工厂是否能满足这些需求?比如,使用RemoveRequestHeader移除Authorization头,或者使用SetStatus直接返回响应,避免转发到下游服务。 另外,用户可能希望这些白名单路由能够处理静态资源、健康检查端点等,这些通常不需要认证。需要确保配置中的路由顺序正确,白名单路由优先于其他路由,并且正确应用过滤器来跳过安全逻辑。 还需要考虑用户是否了解如何组合多个过滤器,比如同时移除请求头和重写路径。可能需要给出具体的配置示例,说明每个过滤器的作用,以及路由的顺序如何影响匹配。 另外,用户可能对动态更新配置有需求,比如通过配置中心动态调整白名单路径。虽然这不涉及自定义过滤器,但可以结合配置中心来实现动态更新,提升灵活性。 最后,需要总结内置过滤器的优缺点,指出在复杂场景下的局限性,比如基于IP或请求头的白名单可能需要自定义过滤器,但在简单路径匹配的情况下,内置过滤器已经足够。同时提醒用户注意路径匹配的安全性和性能影响,避免过度使用通配符。</think>--- ### **不自定义过滤器,仅用内置 `GatewayFilterFactory` 实现路由白名单** Spring Cloud Gateway 虽然没有提供名为 "Whitelist" 的专用过滤器,但可以通过 **灵活组合内置的路由断言(Predicates)和过滤器Filters)** 实现白名单功能。以下是具体实现方案及示例: --- ### **1. 核心实现思路** 1. **定义白名单路径**:通过 `Path` 路由断言匹配白名单路径。 2. **跳过安全逻辑**:使用内置过滤器移除或绕过认证、鉴权等操作(如移除 `Authorization` 请求头)。 3. **优先级控制**:确保白名单路由优先于其他路由执行。 --- ### **2. 完整配置示例(YAML)** ```yaml spring: cloud: gateway: routes: # 白名单路由(优先级最高) - id: whitelist_route uri: http://backend-service # 后端服务地址 predicates: # 匹配白名单路径(支持通配符) - Path=/public/**, /static/**, /actuator/health filters: # 移除认证头(跳过鉴权) - RemoveRequestHeader=Authorization # 可选:直接返回固定响应(如静态资源) # - SetStatus=200 # - SetResponseHeader=Content-Type, text/plain # - SetResponseBody=Hello from Gateway # 通用路由(处理需认证的请求) - id: auth_route uri: http://backend-service predicates: - Path=/** filters: - TokenRelay # 传递OAuth2 Token ``` --- ### **3. 关键内置过滤器说明** 以下过滤器组合可实现白名单逻辑: | **过滤器工厂** | **作用** | **适用场景** | |--------------------------|-------------------------------------------------------------------------|----------------------------------| | `RemoveRequestHeader` | 移除请求头(如 `Authorization`),强制跳过下游服务鉴权。 | 白名单路径无需认证 | | `SetResponseHeader` | 设置响应头,直接返回固定内容(如静态资源)。 | 网关直接响应,不转发到后端服务 | | `SetResponseBody` | 设置固定响应体(如 `{"code":200}`)。 | 快速返回预定义结果 | | `RewritePath` | 重写请求路径(如 `/public/(?<segment>.*)` → `/internal/${segment}`)。 | 路径映射到内部服务接口 | | `StripPrefix` | 去除路径前缀(如 `/static/files/abc.txt` → `/abc.txt`)。 | 静态资源路径优化 | | `RedirectTo` | 重定向到指定URL(如将 `/old/**` 重定向到 `/new/**`)。 | 旧路径跳转 | --- ### **4. 典型场景实现** #### **(1) 静态资源直接响应** ```yaml filters: - SetStatus=200 - SetResponseHeader=Content-Type, text/css - SetResponseBody=body_content_here # 或通过 file:/path/to/resource.css 加载 ``` #### **(2) 跳过认证并转发请求** ```yaml filters: - RemoveRequestHeader=Authorization # 移除JWT Token - RewritePath=/api/public/(?<segment>.*), /internal/${segment} # 路径重写 ``` #### **(3) 直接返回JSON响应** ```yaml filters: - SetResponseHeader=Content-Type, application/json - SetResponseBody={"code": 200, "message": "Public Access"} ``` --- ### **5. 注意事项** 1. **路由顺序** 白名单路由需定义在通用路由之前(YAML 中从上到下优先级递减),确保优先匹配。 2. **路径匹配安全** - 避免过度使用 `/**` 通配符,导致非白名单路径被意外放行。 - 精确匹配敏感路径(如 `/admin/login` 优于 `/admin*`)。 3. **性能影响** 若白名单路径极多(如数百条),建议合并路径规则或使用正则表达式优化匹配效率: ```yaml predicates: - Path=/public/(v1|v2)/resources/.* # 正则匹配多版本路径 ``` 4. **动态更新** 集成配置中心(如 Nacos)实现白名单路径动态刷新: ```yaml predicates: - Path=${nacos.whitelist.paths:/default/public/**} ``` --- ### **6. 局限性及替代方案** | **场景** | **内置过滤器能力** | **替代方案** | |-----------------------------|---------------------------------|----------------------------------| | 基于IP地址的白名单 | ❌ 不支持 | 结合 `RemoteAddr` 路由断言 | | 基于请求头的复杂规则(如Token)| ❌ 不支持 | 自定义全局过滤器 | | 动态规则(如数据库加载) | ❌ 不支持 | 自定义过滤器 + 配置中心 | --- ### **总结** - **完全可行**:通过 `Path` 断言 + `RemoveRequestHeader`/`SetResponse*` 等内置过滤器,无需自定义代码即可实现白名单。 - **适用场景**:路径规则简单、安全逻辑仅需跳过认证或返回固定响应的场景。 - **扩展性**:结合 `RemoteAddr` 路由断言,可扩展实现 IP 白名单等基础功能。 - **复杂度权衡**:若规则涉及多维度条件(如IP+Header+Path),仍需考虑自定义过滤器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值