当前位置:首页 > 技术 > 正文内容

Spring Cloud Zuul 自定义过滤器实现安全鉴权

访客 技术 2026年6月8日 1

在微服务架构中,API 网关不仅负责请求路由和负载均衡,还承担着横切关注点的处理任务,其中最重要的功能之一就是权限控制。通过在网关层实现统一的鉴权逻辑,可以有效避免在每个业务微服务中重复编写校验代码,从而简化系统架构并提高安全性。

为什么在网关层进行过滤

如果让每个微服务独立处理身份验证和授权,会导致大量的代码冗余。虽然可以通过提取公共类库来缓解,但这依然无法从本质上解耦业务逻辑与非业务逻辑。引入 Spring Cloud Zuul 过滤器后,所有进入系统的外部请求都会先经过网关。我们可以在请求被转发到具体微服务之前,拦截并执行签名校验、权限检查等操作。这样,后端微服务只需专注于业务逻辑的实现,降低了开发和维护的复杂度。

ZuulFilter 的核心组件

要实现自定义过滤器,需要继承 ZuulFilter 类并重写其定义的四个核心方法:

  • filterType():返回过滤器的类型,决定其在请求生命周期的哪个阶段执行。常用取值包括 pre(路由前)、route(路由时)、post(路由后)和 error(发生错误时)。
  • filterOrder():定义过滤器的执行顺序。数值越小,优先级越高。
  • shouldFilter():布尔类型,指定该过滤器在什么条件下需要被执行。
  • run():核心业务逻辑所在,用于定义具体的拦截或处理规则。

实战演练:实现 Token 校验过滤器

以下示例展示了如何创建一个名为 TokenValidationFilter 的过滤器,用于检查请求头中是否包含合法的 X-Auth-Token

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;

public class TokenValidationFilter extends ZuulFilter {

    private static final Logger logger = LoggerFactory.getLogger(TokenValidationFilter.class);

    @Override
    public String filterType() {
        // 设置为前置过滤器,在路由之前校验
        return "pre";
    }

    @Override
    public int filterOrder() {
        // 设置执行优先级
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        // 对所有请求生效
        return true;
    }

    @Override
    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();

        logger.info("正在处理请求: {} {}", request.getMethod(), request.getRequestURL().toString());

        // 从 Header 中获取校验令牌
        String securityToken = request.getHeader("X-Auth-Token");

        if (securityToken == null || securityToken.isEmpty()) {
            logger.warn("鉴权失败:请求头中缺失 token");
            
            // 拒绝路由该请求
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(401);
            context.setResponseBody("{\"error\": \"Unauthorized access - Token is missing\"}");
            context.getResponse().setContentType("application/json;charset=UTF-8");
            return null;
        }

        logger.info("鉴权通过");
        return null;
    }
}

配置与启用过滤器

编写完过滤器逻辑后,需要在 Spring Boot 的配置类中将其声明为一个 Bean,以便 Zuul 能够识别并将其加载到过滤链中。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewaySecurityConfig {

    @Bean
    public TokenValidationFilter tokenValidationFilter() {
        return new TokenValidationFilter();
    }
}

功能验证

完成配置并启动网关服务后,可以通过以下场景测试过滤器的有效性:

  1. 无 Token 请求:直接访问网关代理的接口,系统应返回 HTTP 401 状态码,并提示 token 缺失。
  2. 携带 Token 请求:在请求头中添加 X-Auth-Token: some_value 再次发起请求,网关应正常转发请求至目标微服务并返回预期数据。
标签: Spring Cloud

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。