老蒋的知识库

  • 首页
  • 文章归档
  • 关于页面

  • 搜索

Spring Boot Gateway 网关配置,Nacos服务发现注册。

发表于 2025-02-25 | 分类于 Java | 0 | 阅读次数 24
  1. 添加相关配置
  2. 添加过滤器,路由管理器配置,针对路由进行鉴权、服务转发

添加相关配置

pom.xml文件添加mvn包


        <!-- SpringCloud Alibaba Nacos 服务注册 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- SpringCloud Alibaba Nacos 配置中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- spring gateway 网关 -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-gateway</artifactId>
		</dependency>
	</dependencies>

bootstrap.yml添加配置

server:
  port: 8080

spring:
  application:
    name: gateway
  profiles:
    active: dev
  cloud:
    nacos:
      discovery: # 服务注册、发现
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        service: ${spring.application.name}-${spring.profiles.active}
      config:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        file-extension: yml
        shared-configs: # 指定额外的配置文件
          - data-id: application.yml
    loadbalancer:
      nacos:
        enabled: true # 开启nacos负载均衡策略
    gateway:
      routes: # 网关路由配置
        - id: auth-service # 路由id,自定义,只要唯一即可
          #uri: http://127.0.0.1:8088 # 路由的目标地址 http就是固定地址
          uri: lb://auth-${spring.profiles.active} # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/auth/** # 这个是按照路径匹配,只要以 /auth/ 开头就符合要求
          filters: # 路由过滤器,对请求或者响应做出处理
            - StripPrefix=1 # 去掉路径一条前缀,这里是: /auth
          metadata:
            auth-white-list: # 过滤器白名单列表,目前只配置login路由白名单
              - /login/**

此时启动gateway、auth服务,访问http://127.0.0.1:8080/auth/login服务就会自动转发到http://auth-dev/login,auth-dev就是Nacos注册的鉴权服务。
auth服务路由代码可以参考这篇文章最后一段Controller代码: https://halo.ljdzsk.com/archives/springbootswagger3-tong-yi-jie-kou-xiang-ying

添加过滤器,路由管理器配置,针对路由进行鉴权、服务转发


import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class AuthFilter implements GlobalFilter {

    private final RouteMetadataService routeMetadataService;
    private final ObjectMapper objectMapper; // JSON 序列化工具

    private final PathMatcher pathMatcher = new AntPathMatcher();  // Spring内置的路径匹配器

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("开始鉴权");
        Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);

        if (route != null) {
            // 过滤白名单路由鉴权
            List<String> authWhiteList = routeMetadataService.getauthWhiteList(route.getId());
            String path = exchange.getRequest().getURI().getPath();
            if (authWhiteList.stream().anyMatch(pattern -> pathMatcher.match(pattern, path))) {
                return chain.filter(exchange);
            }
        }

        // 从请求头或参数中获取Token
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");

        // 验证Token逻辑(如调用Auth服务)
        if (!isValidToken(token)) {
            return Result.error(HttpStatus.UNAUTHORIZED).toMono(exchange.getResponse(), objectMapper);
        }

        return chain.filter(exchange);
    }

    /***
     * 鉴权判断
     */
    private boolean isValidToken(String token) {
        return false;
    }
}

路由管理服务


import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/***
 * 路由管理
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class RouteMetadataService {

    private final RouteLocator routeLocator;
    private final Map<String, List<String>> routeExcludePaths = new HashMap<>();

    /**
     * 加载所有路由的元数据
     */
    public void loadMetadata() {
        Flux<Route> routes = routeLocator.getRoutes();
        routes.subscribe(route -> {
            // 从元数据获取鉴权白名单,路径在白名单中,无需鉴权
            List<String> authWhiteList = Optional.ofNullable(route.getMetadata().get("auth-white-list"))
                    .map(obj -> {
                        if (obj instanceof List) {
                            // 直接转换为List<String>
                            return (List<String>) obj;
                        } else if (obj instanceof Map) {
                            // 如果是Map,提取所有值组成List
                            Map<?, ?> map = (Map<?, ?>) obj;
                            return map.values().stream()
                                    .filter(String.class::isInstance)
                                    .map(String.class::cast)
                                    .collect(Collectors.toList());
                        } else {
                            log.warn("auth-white-list 类型不匹配: {}", obj.getClass().getName());
                            return List.<String>of();
                        }
                    })
                    .orElse(List.of());  // 默认返回空列表
            routeExcludePaths.put(route.getId(), authWhiteList);
        });
    }

    /**
     * 获取指定路由的白名单路径列表
     */
    public List<String> getauthWhiteList(String routeId) {
        return routeExcludePaths.getOrDefault(routeId, List.of());
    }

    /**
     * 动态路由更新时调用此方法刷新缓存
     */
    @PostConstruct
    public void refreshMetadata() {
        routeExcludePaths.clear();
        loadMetadata();
    }
}

此时启动gateway、auth服务,访问:http://127.0.0.1:8080/auth/login可以正常转发,http://127.0.0.1:8080/auth/login1 会提示没有权限。

  • 本文作者: jagger
  • 本文链接: /archives/springbootgateway-wang-guan-pei-zhi-nacos-fu-wu-fa-xian-zhu-ce-
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
Swagger Ui 404 问题,更新配置后不显示Controller对应API问题。
Spring boot 加载公共组件提示Bean无法注入
jagger

jagger

66 日志
31 分类
0 标签
Creative Commons
0%
© 2026 jagger
由 Halo 强力驱动