【实现微服务集成satoken在网关gateway处统一鉴权】

这篇具有很好参考价值的文章主要介绍了【实现微服务集成satoken在网关gateway处统一鉴权】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 内容说明

本文旨在使用开源轻量级 Java 权限认证框架sa-token+springcloud-gateway实现微服务在网关处统一鉴权。sa-token参考地址:https://sa-token.cc/doc.html#/
项目按照业务分为三个板块,如图:

  1. api(也就是微服务中各种api接口,不涉及任何权限相关代码,只提供服务)
  2. auth(认证中心,实现登陆逻辑)
  3. gateway(网关,实现转发等,主要是统一鉴权)
    网关统一鉴权,java,微服务,gateway

2. 项目实现

首先在idea创建一个项目mirco,然后在项目下依次创建三个module,这就不展开说了。接下来各模块填充内容。

2.1. auth模块

2.1.1. pom.xml依赖

主要是web、satoken、satoken整合redis:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.3.5.RELEASE</version>
    </dependency>
    <!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
    <dependency>
        <groupId>cn.dev33</groupId>
        <artifactId>sa-token-spring-boot-starter</artifactId>
        <version>1.34.0</version>
    </dependency>
    <!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
    <dependency>
        <groupId>cn.dev33</groupId>
        <artifactId>sa-token-dao-redis-jackson</artifactId>
        <version>1.34.0</version>
    </dependency>
    <!-- 提供Redis连接池 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
</dependencies>

2.1.2. controller类

提供登陆接口,实现登陆并返回登陆成功的token给前端:

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthController {

    @GetMapping("/auth/doLogin")
    public SaResult doLogin(String username, String password) {
        // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
        if ("admin".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
        } else if ("super".equals(username) && "123456".equals(password)) {
            StpUtil.login(10002);
        }else {
            return SaResult.error("登录失败");
        }
        // 第3步,返回给前端
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return SaResult.ok("登录成功").setData(tokenInfo);
    }
}

2.1.3. 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AuthApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthApplication.class, args);
    }
}

2.1.4. application.yml配置文件

server:
  port: 8082
spring:
  # redis配置
  redis:
    # Redis数据库索引(默认为0)
    database: 1
    # Redis服务器地址
    host: 127.0.0.1
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    # password:
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池最大连接数
        max-active: 200
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
        # 连接池中的最大空闲连接
        max-idle: 10
        # 连接池中的最小空闲连接
        min-idle: 0

2.2. gateway模块

2.2.1. pom.xml依赖

主要是gateway、satoken、satoken整合redis:

<dependencies>
    <!-- springCloud gateway -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
        <version>2.2.10.RELEASE</version>
    </dependency>
    <!-- httpClient依赖,缺少此依赖api网关转发请求时可能发生503错误 -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    <dependency>
        <groupId>cn.dev33</groupId>
        <artifactId>sa-token-reactor-spring-boot-starter</artifactId>
        <version>1.34.0</version>
    </dependency>
    <!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
    <dependency>
        <groupId>cn.dev33</groupId>
        <artifactId>sa-token-dao-redis-jackson</artifactId>
        <version>1.34.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
</dependencies>

2.2.2. 全局过滤器

主要是配置路由进行拦截鉴权,这里是整个鉴权的核心,具体的路由配置规则参考sa-token官网:

import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * [Sa-Token 权限认证] 配置类
 */
@Configuration
public class SaTokenConfigure {
    // 注册 Sa-Token全局过滤器 
    @Bean
    public SaReactorFilter getSaReactorFilter() {
        return new SaReactorFilter()
                // 拦截地址
                .addInclude("/**")    /* 拦截全部path */
                // 开放地址
                .addExclude("/favicon.ico")
                // 鉴权方法:每次访问进入
                .setAuth(obj -> {
                    // 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
                    SaRouter.match("/**", "/auth/doLogin", r -> StpUtil.checkLogin());

                    // 权限认证 -- 不同模块, 校验不同权限
                    SaRouter.match("/api/test1", r -> StpUtil.checkPermission("api.test1"));
                    SaRouter.match("/api/test2", r -> StpUtil.checkPermission("api.test2"));
                    SaRouter.match("/api/test3", r -> StpUtil.checkRoleOr("admin", "super"));

                    // 更多匹配 ...  */
                })
                // 异常处理方法:每次setAuth函数出现异常时进入
                .setError(e -> {
                    return SaResult.error(e.getMessage());
                })
                ;
    }
}

2.2.3. 自定义权限接口

主要是定义用户拥有的权限和角色,我这里直接写死的,实际项目中通常应该是auth认证模块登陆后从数据库查出用户的角色权限缓存到redis,然后这里再从redis取出来。

import cn.dev33.satoken.stp.StpInterface;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义权限验证接口扩展,在需要鉴权时自动调用
 */
@Component
public class StpInterfaceImpl implements StpInterface {

    /**
     * 返回一个账号所拥有的权限码集合
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询权限
        List<String> list = new ArrayList<>();
        if (Integer.parseInt(loginId.toString()) == 10001) {
            list.add("api.test1");
        } else if (Integer.parseInt(loginId.toString()) == 10002) {
            list.add("api.test2");
        }
        return list;
    }

    /**
     * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验)
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        // 本list仅做模拟,实际项目中要根据具体业务逻辑来查询角色
        List<String> list = new ArrayList<>();
        if (Integer.parseInt(loginId.toString()) == 10001) {
            list.add("admin");
        } else if (Integer.parseInt(loginId.toString()) == 10002) {
            list.add("super");
        }
        return list;
    }

}

2.2.4. 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

2.2.5. application.yml配置文件

server:
  port: 8083
spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: api
          uri: http://127.0.0.1:8081
          predicates:
            - Path=/api/**
        - id: auth
          uri: http://127.0.0.1:8082
          predicates:
            - Path=/auth/**
  redis:
    # Redis数据库索引(默认为0)
    database: 1
    # Redis服务器地址
    host: 127.0.0.1
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    # password:
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池最大连接数
        max-active: 200
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
        # 连接池中的最大空闲连接
        max-idle: 10
        # 连接池中的最小空闲连接
        min-idle: 0

2.3. auth模块

2.3.1. pom.xml依赖

主要是web:

<dependencies>
    <!-- SpringBoot Web模块 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

2.3.2. controller类

提供一些接口,用来验证satoken权限:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @GetMapping("/api/test1")
    public String test1() {
        return "访问成功--只有《api.test1》权限的才能访问";
    }

    @GetMapping("/api/test2")
    public String test2() {
        return "访问成功--只有《api.test2》权限的才能访问";
    }

    @GetMapping("/api/test3")
    public String test3() {
        return "访问成功--拥有《admin或者super角色》可以访问";
    }

    @GetMapping("/api/test4")
    public String test4() {
        return "访问成功--无需权限,登陆即可访问";
    }

}

2.3.3. 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiApplication.class, args);
    }
}

2.3.4. application.yml配置文件

server:
  port: 8081

3. 项目测试

  1. 首先通过网关登陆:http://localhost:8083/auth/doLogin?username=admin&password=123456
    网关统一鉴权,java,微服务,gateway
    如图正确的账户密码登陆成功返回token,这里登陆的admin用户。

  2. 不带token访问,访问失败:http://localhost:8083/api/test1
    网关统一鉴权,java,微服务,gateway

  3. 携带token访问,访问成功:http://localhost:8083/api/test1
    网关统一鉴权,java,微服务,gateway

  4. 访问无权限的接口失败:http://localhost:8083/api/test2

网关统一鉴权,java,微服务,gateway

  1. 访问有角色权限的接口成功:http://localhost:8083/api/test3
    网关统一鉴权,java,微服务,gateway

4. 项目总结

至此,我们完成了gateway处统一使用sa-token鉴权。以上只是最基础的网关统一鉴权的使用,更深层的比如内外网隔离等请自行参考sa-token官网。个人觉得sa-token相当牛逼,十分容易上手,不管你是单体、前后端分离还是微服务项目,都能轻松集成。相比于springsecurity学习成本降低很多。
另外本博客涉及的代码已全部包含在文章里了,就不另外贴了。文章来源地址https://www.toymoban.com/news/detail-693488.html

到了这里,关于【实现微服务集成satoken在网关gateway处统一鉴权】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Gateway + Oauth2 + Jwt网关统一鉴权

    之前文章里说过,分布式系统的鉴权有两种方式,一是在网关进行统一的鉴权操作,二是在各个微服务里单独鉴权。 第二种方式比较常见,代码网上也是很多。今天主要是说第一种方式。 重要前提:需要收集各个接口的uri路径和所需权限列表的对应关系,并存入缓存。 服务

    2024年02月03日
    浏览(46)
  • SpringCloud搭建微服务之Gateway+Jwt实现统一鉴权

    在微服务项目中,需要对整个微服务系统进行权限校验,通常有两种方案,其一是每个微服务各自鉴权,其二是在网关统一鉴权,第二种方案只需要一次鉴权就行,避免了每个微服务重复鉴权的麻烦,本文以网关统一鉴权为例介绍如何搭建微服务鉴权项目。 本文案例中共有四

    2024年02月13日
    浏览(51)
  • 微服务-统一网关Gateway

    对用户请求做身份认证、权限校验 将用户请求路由到微服务,并实现负载均衡 对用户请求做限流 创建新module,命名为Gateway,引入依赖(1.SpringCloudGateway依赖;2.Eureka客户端依赖或者nacos的服务发现依赖)。在本案例中使用的是Eureka。 配置Application.yml的网关服务 路由id:路由

    2024年02月08日
    浏览(43)
  • 【微服务】八. 统一网关gateway

    网关功能: 身份认证和权限校验 服务路由、负载均衡 请求限流 网关的技术实现 在SpringCloud中网关的实现包括两种: gateway zuul Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。 网关的作用 对

    2024年02月07日
    浏览(50)
  • 微服务中间件--统一网关Gateway

    网关功能: 身份认证和权限校验 服务路由、负载均衡 请求限流 网关的技术实现 在SpringCloud中网关的实现包括两种: gateway zuul Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。 搭建网关服务

    2024年02月11日
    浏览(41)
  • Spring Cloud Gateway集成Swagger实现微服务接口文档统一管理及登录访问

    本文将介绍如何在 Spring Cloud 微服务中使用 Swagger 网关来统一管理所有微服务的接口文档,并通过 Spring Security 实现登录后才能访问 Swagger 文档,以确保接口数据的安全访问。 在开始之前,需要假设你已经完成了 Spring Cloud Gateway 的相关配置,并且已经了解了基本的网关配置知

    2024年02月05日
    浏览(43)
  • SpringCloud微服务 【实用篇】| 统一网关Gateway

    目录 一:统一网关Gateway 1. 为什么需要网关 2. gateway快速入门 3. 断言工厂 4. 过滤器工厂 5. 全局过滤器 6. 跨域问题 前面我们已经学习了注册中心Eureka、Nacos和配置管理中心Nacos;但是此时存在很多安全的问题,服务器摆在那里谁都可以进行访问! 网关功能: ① 身份认证和权

    2024年02月04日
    浏览(43)
  • Spring Cloud Gateway + Oauth2 实现统一认证和鉴权!

    micro-oauth2-gateway:网关服务,负责请求转发和鉴权功能,整合Spring Security+Oauth2; micro-oauth2-auth:Oauth2认证服务,负责对登录用户进行认证,整合Spring Security+Oauth2; micro-oauth2-api:受保护的API服务,用户鉴权通过后可以访问该服务,不整合Spring Security+Oauth2。 我们首先来搭建认

    2024年01月16日
    浏览(62)
  • SpringCloud网关Gateway认证鉴权【SpringCloud系列7】

    SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见。 程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCloud 微服务系列项目开发 本文章是系列文章中的一篇 1、SpringCloud 项目基础工程搭建 【SpringCloud系列1】 2、S

    2024年02月09日
    浏览(49)
  • 【Java】微服务——Gateway网关

    Gateway网关是我们服务的守门神,所有微服务的统一入口。 网关的 核心功能特性 : 请求路由 权限控制 限流 架构图: 权限控制 :网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。 路由和负载均衡 :一切请求都必须先经过gateway,但网关不处理业

    2024年02月04日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包