SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口

简介: SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口


来源:zhanjq.blog.csdn.net/article/details/127574020


本文主要内容是通过SpringCloud Gateway构建一个网关微服务,作为统一的认证授权和访问入口。

配置文件

先引入相关依赖,对应的pom文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>oauth2-demo</artifactId>
        <groupId>com.zjq</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ms-gateway</artifactId>
    <dependencies>
        <!-- spring cloud gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!-- eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- commons 公共项目 -->
        <dependency>
            <groupId>com.zjq</groupId>
            <artifactId>commons</artifactId>
            <version>1.0-SNAPSHOT</version>
            <!-- 和 webflux 冲突 -->
            <exclusions>
                <exclusion>
                    <groupId>com.battcn</groupId>
                    <artifactId>swagger-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 自定义的元数据依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

网关服务的yml配置内容如下:

server:
  port: 80
spring:
  application:
    name: ms-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启配置注册中心进行路由功能
          lower-case-service-id: true # 将服务名称转小写
      routes:
        - id: ms-users
          uri: lb://ms-users
          predicates:
            - Path=/users/**
          filters:
            - StripPrefix=1
        - id: ms-oauth2-server
          uri: lb://ms-oauth2-server
          predicates:
            - Path=/auth/**
          filters:
            - StripPrefix=1
secure:
  ignore:
    urls: # 配置白名单路径
      - /actuator/**
      - /auth/oauth/**
      - /users/signin
> 基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
>
> * 项目地址:<https://github.com/YunaiV/ruoyi-vue-pro>
> * 视频教程:<https://doc.iocoder.cn/video/>
# 配置 Eureka Server 注册中心
eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka/
logging:
  pattern:
    console: '%d{HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n'

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

请求白名单配置

加载配置文件中的配置,注入到spring容器中。

secure:
  ignore:
    urls: # 配置白名单路径
      - /actuator/**
      - /auth/oauth/**
      - /users/signin
/**
 * 网关白名单配置
 * @author zjq
 */
@Data
@Component
@ConfigurationProperties(prefix = "secure.ignore")
public class IgnoreUrlsConfig {
    private List<String> urls;
}

异常处理和rest请求配置

异常处理在全局过滤器中会有用到,代码如下:

@Component
public class HandleException {
    @Resource
    private ObjectMapper objectMapper;
    public Mono<Void> writeError(ServerWebExchange exchange, String error) {
        ServerHttpResponse response = exchange.getResponse();
        ServerHttpRequest request = exchange.getRequest();
        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        ResultInfo resultInfo = ResultInfoUtil.buildError(ApiConstant.NO_LOGIN_CODE, ApiConstant.NO_LOGIN_MESSAGE, request.getURI().getPath());
        String resultInfoJson = null;
        DataBuffer buffer = null;
        try {
            resultInfoJson = objectMapper.writeValueAsString(resultInfo);
            buffer = response.bufferFactory().wrap(resultInfoJson.getBytes(Charset.forName("UTF-8")));
        } catch (JsonProcessingException ex) {
            ex.printStackTrace();
        }
        return response.writeWith(Mono.just(buffer));
    }
}

申请授权和认证过程中需要远程调用其他接口,所以我们引入rest请求配置,代码如下:

/**
 * REST请求配置
 * @author zjq
 */
@Configuration
public class RestTemplateConfiguration {
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

全局过滤器配置

配置好了白名单,我们需要在网关过滤器中使用该白名单配置,放行对应的白名单,网关过滤器需要实现全局过滤器接口org.springframework.cloud.gateway.filter.GlobalFilter和过滤器顺序接口org.springframework.core.Ordered相关代码如下:

/**
 * 网关全局过滤器
 * @author zjq
 */
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Resource
    private IgnoreUrlsConfig ignoreUrlsConfig;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private HandleException handleException;
    /**
     * 身份校验处理
     *
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 判断当前的请求是否在白名单中
        AntPathMatcher pathMatcher = new AntPathMatcher();
        boolean flag = false;
        String path = exchange.getRequest().getURI().getPath();
        for (String url : ignoreUrlsConfig.getUrls()) {
            if (pathMatcher.match(url, path)) {
                flag = true;
                break;
            }
        }
        // 白名单放行
        if (flag) {
            return chain.filter(exchange);
        }
        // 获取 access_token
        String access_token = exchange.getRequest().getQueryParams().getFirst("access_token");
        // 判断 access_token 是否为空
        if (StringUtils.isBlank(access_token)) {
            return handleException.writeError(exchange, "请登录");
        }
        // 校验 token 是否有效
        String checkTokenUrl = "http://ms-oauth2-server/oauth/check_token?token=".concat(access_token);
        try {
            // 发送远程请求,验证 token
            ResponseEntity<String> entity = restTemplate.getForEntity(checkTokenUrl, String.class);
            // token 无效的业务逻辑处理
            if (entity.getStatusCode() != HttpStatus.OK) {
                return handleException.writeError(exchange,
                        "Token was not recognised, token: ".concat(access_token));
            }
            if (StringUtils.isBlank(entity.getBody())) {
                return handleException.writeError(exchange,
                        "This token is invalid: ".concat(access_token));
            }
        } catch (Exception e) {
            return handleException.writeError(exchange,
                    "Token was not recognised, token: ".concat(access_token));
        }
        // 放行
        return chain.filter(exchange);
    }
    /**
     * 网关过滤器的排序,数字越小优先级越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

测试验证

登录:

获取当前登录用户信息:

退出登录:



相关文章
|
3月前
|
存储 缓存 负载均衡
Gateway 网关坑我! 被这个404 问题折腾了一年?
小富分享了一个困扰团队一年多的 SpringCloud Gateway 路由 404 问题。通过日志追踪和源码分析,发现是网关在 Nacos 配置更新后未能正确清理旧的路由权重缓存,导致负载均衡时仍使用已删除的路由数据。最终通过监听路由刷新事件并手动更新缓存,成功解决了问题。
783 125
Gateway 网关坑我! 被这个404 问题折腾了一年?
|
3月前
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
2月前
|
缓存 JSON NoSQL
别再手写过滤器!SpringCloud Gateway 内置30 个,少写 80% 重复代码
小富分享Spring Cloud Gateway内置30+过滤器,涵盖请求、响应、路径、安全等场景,无需重复造轮子。通过配置实现Header处理、限流、重试、熔断等功能,提升网关开发效率,避免代码冗余。
374 1
|
2月前
|
机器学习/深度学习 Kubernetes API
【Azure APIM】自建网关(self-host gateway)收集请求的Header和Body内容到日志中的办法
在Azure API Management中,通过配置trace策略可完整记录API请求的Header和Body信息。在Inbound和Outbound策略中分别使用context.Request/Response.Headers和Body.As&lt;string&gt;方法捕获数据,并写入Trace日志,便于排查与审计。
127 7
|
4月前
|
安全 虚拟化
Omnissa Secure Email Gateway 2.33 - 电子邮件网关
Omnissa Secure Email Gateway 2.33 - 电子邮件网关
111 0
|
5月前
|
前端开发 Java API
Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
377 0
|
6月前
|
应用服务中间件 网络安全 数据安全/隐私保护
网关服务器配置指南:实现自动DHCP地址分配、HTTP服务和SSH无密码登录。
哇哈哈,道具都准备好了,咱们的魔术秀就要开始了。现在,你的网关服务器已经魔法满满,自动分配IP,提供网页服务,SSH登录如入无人之境。而整个世界,只会知道效果,不会知道是你在幕后操控一切。这就是真正的数字世界魔法师,随手拈来,手到擒来。
364 14
|
监控 负载均衡 安全
微服务(五)-服务网关zuul(一)
微服务(五)-服务网关zuul(一)
|
安全 5G 网络性能优化
深入理解5G中的SAEGW:服务网关边界
【10月更文挑战第9天】
509 0
|
运维 Kubernetes 安全
利用服务网格实现全链路mTLS(一):在入口网关上提供mTLS服务
阿里云服务网格(Service Mesh,简称ASM)提供了一个全托管式的服务网格平台,兼容Istio开源服务网格,用于简化服务治理,包括流量管理和拆分、安全认证及网格可观测性,有效减轻开发运维负担。ASM支持通过mTLS提供服务,要求客户端提供证书以增强安全性。本文介绍如何在ASM入口网关上配置mTLS服务并通过授权策略实现特定用户的访问限制。首先需部署ASM实例和ACK集群,并开启sidecar自动注入。接着,在集群中部署入口网关和httpbin应用,并生成mTLS通信所需的根证书、服务器证书及客户端证书。最后,配置网关上的mTLS监听并设置授权策略,以限制特定客户端对特定路径的访问。
426 2

热门文章

最新文章