首页 > 编程语言 >java脚手架系列9-统一权限认证gateway

java脚手架系列9-统一权限认证gateway

时间:2024-10-22 11:49:21浏览次数:7  
标签:java nacos 路由 org import 脚手架 gateway cloud

之所以想写这一系列,是因为之前工作过程中有几次项目是从零开始搭建的,而且项目涉及的内容还不少。在这过程中,遇到了很多棘手的非业务问题,在不断实践过程中慢慢积累出一些基本的实践经验,认为这些与业务无关的基本的实践经验其实可以复刻到其它项目上,在行业内可能称为脚手架,因此决定将此java基础脚手架的搭建总结下来,分享给大家使用。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中主要使用基本框架是 spring-boo-2.3.12.RELEASE和spring-cloud.-Hoxton.SR12,所有代码都在commonFramework项目上:https://github.com/forever1986/commonFramework/tree/master

目录

1 gateway

之所以将gateway放在这里讲,是因为承接上一篇的OAuth2,其中gateway有一个重要的功能就是鉴权,可以结合OAuth2进行鉴权。
在我们使用微服务架构的时候,免不了需要一个网关,而对于java项目来说,gateway是一个很好的选择。一般实践中,gateway有以下功能:

  • 路由转发:根据请求的特定条件(如 URL路径、请求参数、请求头等)来将请求转发到后端的多个服务,并支持动态路由配置
  • 过滤功能:提供了一套过滤器机制,允许开发人员对请求进行修改和验证,以及应用各种策略,如认证、安全、监控/指标、限流、日志、请求转发/重试等
  • 容错处理:集成断路器(Hystrix),为微服务网关提供容错处理的功能
  • 服务发现:与服务注册中心集成,动态从服务注册中心获取服务信息并进行路由
  • 请求转发:进行请求的协议转换,比如将 HTTP 请求转换成 WebSocket 请求
  • 请求限流:支持通过配置限流规则,对请求进行限流,防止恶意请求或异常情况下的流量冲击

下面以动态读取路由配置+过滤功能,实现gateway的路由转发可以动态加载,以及实现鉴权功能

2 动态加载路由表

参考gateway子模块

在实际应用中,我们不可能将路由配置放入项目的yaml配置文件中,这样修改路由时,都需要重新启动或者发布。这时候,配置中心就起到动态配置路由转发的存储功能,同时gateway也提供RouteDefinitionRepository可进行路由表动态加载。

原理:将路由配置文件放入nacos中,gateway子模块通过实现RouteDefinitionRepository,监听nacos的路由配置文件,实现动态更新路由配置

1)创建gateway子模块,引入以下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--监听配置文件的更新 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--获取配置文件 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2)配置bootstrap.yml,要配置服务发现和配置中心的信息

server:
  port: 9991
spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
      config:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        file-extension: yaml
        group: DEFAULT_GROUP
        prefix: ${spring.application.name}

3)实现NacosRouteDefinitionRepository(实现RouteDefinitionRepository),用于自动监听配置文件并刷新路由表

package com.demo.route.config;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

/**
 * nacos路由数据源
 */
@Component
public class NacosRouteDefinitionRepository implements RouteDefinitionRepository {

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

    private static final String SCG_DATA_ID = "cloud-gateway-service";
    private static final String SCG_GROUP_ID = "DEFAULT_GROUP";

    private final ApplicationEventPublisher publisher;

    private final NacosConfigManager nacosConfigManager;

    public NacosRouteDefinitionRepository(ApplicationEventPublisher publisher, NacosConfigManager nacosConfigManager) {
        this.publisher = publisher;
        this.nacosConfigManager = nacosConfigManager;
        addListener();
    }

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> routeDefinitionList = new ArrayList<>(0);
        try {
            String configContent = nacosConfigManager.getConfigService().getConfig(SCG_DATA_ID, SCG_GROUP_ID, 5000);

            if (StringUtils.isNotEmpty(configContent)) {
                routeDefinitionList = JSON.parseArray(configContent, RouteDefinition.class);
            }
        } catch (NacosException e) {
            logger.error("从Nacos加载配置的动态路由信息异常", e);
        }
        return Flux.fromIterable(routeDefinitionList);
    }

    /**
     * 添加Nacos监听
     */
    private void addListener() {
        try {
            nacosConfigManager.getConfigService()
                    .addListener(SCG_DATA_ID, SCG_GROUP_ID, new Listener() {

                        @Override
                        public Executor getExecutor() {
                            return null;
                        }

                        @Override
                        public void receiveConfigInfo(String configInfo) {
                            publisher.publishEvent(new RefreshRoutesEvent(this));
                        }
                    });
        } catch (NacosException e) {
            logger.error("添加Nacos监听异常", e);
        }
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return null;
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return null;
    }
}

4)设置GatewayApplication设置@EnableDiscoveryClient注册到nacos
5)在nacos的public命名空间和DEFAULT_GROUP分组中,配置nacos的路由配置名为:cloud-gateway-service的json文件

[
  {
    "id": "baidu",
    "order": 0,
    "predicates": [{
      "args": {
        "pattern": "/baidu/**"
      },
      "name": "Path"
    }],
    "uri": "http://www.baidu.com",
    "filters": [{
      "args": {
        "_genkey_0": "2"
      },
      "name": "StripPrefix"
    }]
  },
  {
    "id": "manager",
    "predicates": [{
      "args": {
        "pattern": "/manager/**"
      },
      "name": "Path"
    }],
    "uri": "http://localhost:9981",
    "filters": [{
      "args": {
        "_genkey_0": "1"
      },
      "name": "StripPrefix"
    }]
  }
]

6)通过请求以下访问,可以得到转发;同时你可以在nacos上面修改cloud-gateway-service的json文件路由,可以测试动态刷新
http://localhost:8891/baidu/aa
http://localhost:8891/business/business

3 鉴权功能

参考gateway子模块

网关的过滤功能:提供了一套过滤器机制,允许开发人员对请求进行修改和验证,以及应用各种策略,如认证、安全、监控/指标、限流、日志、请求转发/重试等。我们这里的鉴权就是使用过滤功能。在配置鉴权功能之前,我们有必要了解一下内容:

  • 鉴权原理:在系列8中我们讲过security、JWT、oauth的内容,这里利用auth-authentication子模块生成token,我们知道验证token的有效性2种方法,一种是使用访问auth-authentication子模块的access_token接口验证,一种是通过RSA非对称加密验证。这里的token采用RSA非对称加密验证(这是因为本身路由访问非常频繁的服务,不适合频繁访问access_token接口)。
  • gateway过滤:在gateway中有3个比较重要的过滤:ReactiveAuthenticationManager->ReactiveAuthorizationManager->Gateway Filters。

1)其中ReactiveAuthenticationManager用于封装JWT为OAuth2Authentication并判断Token的有效性;
2)ReactiveAuthorizationManager用于基于URL的鉴权;
3)Gateway Filters是网关的过滤流程。

下面我们通过配置JWT+RSA的解密对token进行认证,另外通过实现ReactiveAuthorizationManager对其进行鉴权。
1)引入以下依赖:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

3)编写ResourceServerManager(实现ReactiveAuthorizationManager),实现其check接口,获得用户信息,对权限进行判断(这里只是演示一下,没有实际权限判断代码,实际业务中可以加入一些权限判断,比如路由权限、RABC等业务判断功能)
4)编写ResourceServerConfig,通过注入securityWebFilterChain类,将JWT认证和ResourceServerManager都设置到过滤链中
5)在ResourceServerConfig中,通过注入jwtAuthenticationConverter,实现JWT+RSA的公钥,对token进行认证
6)编写SecurityGlobalFilter(实现GlobalFilter,和Ordered),做最后处理(当然如果没有此需求,也可以不做处理)
7)通过请求以下访问,可以得到转发(前提是你需要在header中增加token)
http://localhost:8891/baidu/aa
http://localhost:8891/business/business

标签:java,nacos,路由,org,import,脚手架,gateway,cloud
From: https://blog.csdn.net/linwu_2006_2006/article/details/142986065

相关文章

  • 挑战中,Java面试题复习第4天,坚持就是胜利。
    码城|第4期一分钟吃透Java面试题【悟空非空也】 ......
  • JAVA开源项目 基于Vue和SpringBoot母婴商城系统
    本文项目编号T030,文末自助获取源码\color{red}{T030,文末自助获取源码}......
  • Java 在 GIS 领域的学习路线?
    1、跨平台性Java具有跨平台的特性,Java在地理信息系统(GIS)领域发挥着重要作用,具体表使现得在不同操作系统上能够一致地运行。这对于GIS应用而言尤为重要,因为GIS在系统常常需要在多种操作系统下运行,以以下满足用户的几不同需个求。2、强大的图形界面和用户体验Java提供丰富的图......
  • java+vue计算机毕设反诈骗推广系统【开题+程序+论文+源码】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的迅猛发展,网络诈骗案件层出不穷,严重危害了人民群众的财产安全与合法权益。诈骗手段不断翻新,从传统的电话诈骗、短信诈骗,到近年来兴起的......
  • java+vue计算机毕设大学生在线学习监视系统【开题+程序+论文+源码】
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和教育信息化的不断推进,在线学习已成为大学生获取知识、提升技能的重要途径。然而,在线学习的自主性和灵活性也带来了一系列......
  • 2024常用 gui [转] Java Python C++ C# JavaScript Go Dart Swift
    下面就介绍一下热门编程语言对应的gui框架。JavaSwing:Java的基础GUI工具包,虽然年代较久,但仍然被广泛使用。JavaFX:现代的JavaGUI工具包,用于替代Swing,提供了更丰富的界面设计和动画效果支持。ApachePivot:一个开源的富互联网应用(RIA)框架,使用Java和XML来构建桌面和Web应用程序的......
  • 210基于java ssm springboot垃圾分类回收预约管理系统垃圾站点(源码+文档+运行视频+讲
     文章目录系列文章目录前言一、详细视频演示二、项目部分实现截图三、技术栈后端框架springboot后端框架springboot持久层框架MyBaitsPlus系统测试四、代码参考源码获取前言......
  • SpringBoot启动报错java.nio.charset.MalformedInputException: Input length =1
    启动springboot项目时,出现了以下报错:defaultPattern_IS_UNDEFINEDdefaultPattern_IS_UNDEFINEDdefaultPattern_IS_UNDEFINEDjava.lang.IllegalStateException:Failedtoloadpropertysourcefromlocation'classpath:/application-local.yaml' atorg.springframework......
  • Java反序列化 - CC1链 (代码审计)
    R###一、环境准备:Java环境:Java_1.8.0_8u65ApacheCommonsCollections3.2.2版本二、漏洞简述:cc链是Apachecommonscollections反序列漏洞利用链的简称。可以通过构造恶意类,利用Java反序列化漏洞进行RCE。漏洞复现:CC1链源头:org.apache.commons.collections.Transformer#tr......
  • JAVA注解:注解的作用,注解的语法,注解的使用,注解与反射的综合应用
    1什么是注解jdk5提供了一个新的应用Annotation,注解,注释与之前所学的注释的区别之前的注释:是给程序员看,让程序员知道程序(代码)有什么用,实现了什么功能今天的注解:是给编辑器或jvm看的。在编译和运行时提供一些信息,按照信息完成后续的工作我们在开发中经常使用注解作......