当前位置: 首页 > news >正文

8.15日学习打卡---Spring Cloud Alibaba(三)

8.15日学习打卡

目录:

  • 8.15日学习打卡
    • 为什么需要服务网关
    • Higress是什么
    • 安装DockerCompose
    • 部署Higress
    • 创建网关微服务模块
    • Higress路由配置
    • Higress策略配置-跨域配置
    • Higress解决如何允许跨域
    • Higress策略配置之什么是HTTP认证
    • Higress策略配置-Basic 认证
    • 什么是JWT认证
    • JWT方式
    • JWT原理
    • 载荷 / Payload
    • 创建认证中心微服务
    • 编写JWT工具类生成jwt
    • 编写JWT工具类解密Token
    • 认证中心微服务颁发Token令牌
    • JWT配置
    • Key 认证
    • 请求屏蔽

在这里插入图片描述

为什么需要服务网关

传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。
在这里插入图片描述
服务网关的基本功能
在这里插入图片描述

微服务网关的作用:

  • 提供了统一访问入口,降低了服务受攻击面
  • 提供了统一跨域解决方案
  • 提供了统一日志记录操作,可以进行统一监控
  • 提供了统一权限认证支持
  • 提供了微服务限流功能,可以保护微服务,防止雪崩效应发生

主流网关的对比与选型

  • Kong 网关:Kong 的性能非常好,非常适合做流量网关,但是对于复杂系统不建议业务网关用 Kong,主要是工程性方面的考虑
  • Zuul1.x 网关:Zuul 1.0 的落地经验丰富,但是性能差、基于同步阻塞IO,适合中小架构,不适合并发流量高的场景,因为容易产生线程耗尽,导致请求被拒绝的情况
  • gateway 网关:功能强大丰富,性能好,官方基准测试 RPS (每秒请求数)是Zuul的1.6倍,能与 SpringCloud 生态很好兼容,单从流式编程+支持异步上也足以让开发者选择它了。
  • Higress:一个遵循开源Ingress/Gateway API标准,提供流量调度、服务治理、安全防护三合一的高集成、易使用、易扩展、热更新的下一代云原生网关。

Higress是什么

在这里插入图片描述
Higress是什么
Higress是基于阿里内部的Envoy Gateway实践沉淀、以开源Istio + Envoy为核心构建的下一代云原生网关,实现了流量网关 + 微服务网关 + 安全网关三合一的高集成能力,深度集成Dubbo、Nacos、Sentinel等微服务技术栈,能够帮助用户极大的降低网关的部署及运维成本且能力不打折。
在这里插入图片描述
传统网关分类
行业中通常把网关分为两个大类:流量网关与业务网关,流量网关主要提供全局性的、与后端业务无关的策略配置,例如阿里内部的的统一接入网关Tengine就是典型的流量网关;业务网关顾名思义主要提供独立业务域级别的、与后端业务紧耦合策略配置,随着应用架构模式从单体演进到现在的分布式微服务,业务网关也有了新的叫法 - 微服务网关(图示说明如下)。在目前容器技术与K8s主导的云原生时代,下一代网关模式依然是这样吗?

在这里插入图片描述
Higress定位
在虚拟化时期的微服务架构下,业务通常采用流量网关 + 微服务网关的两层架构,流量网关负责南北向流量调度和安全防护,微服务网关负责东西向流量调度和服务治理,而在容器和 K8s 主导的云原生时代,Ingress 成为 K8s 生态的网关标准,赋予了网关新的使命,使得流量网关 + 微服务网关合二为一成为可能。
在这里插入图片描述

安装DockerCompose

在这里插入图片描述
关闭防火墙

systemctl stop firewalld

设置安装仓库

#安装yum的工具包
yum install -y yum-utils \device-mapper-persistent-data \lvm2 --skip-broken
#更新本地镜像源
# 设置docker镜像源
yum-config-manager \--add-repo \https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.reposed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
#将软件包信息提前在本地索引缓存,用来提高搜索安装软件的速度,建议执行这个命令可以提升yum安装的速度。
yum makecache fast

安装docker引擎

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

启动docker

systemctl start docker

设置docker自启动

systemctl enable docker

测试docker是否安装成功

docker run hello-world

部署Higress

在这里插入图片描述
搭建Higress
在安装之前要保证Docker安装成功并且成功安装Docker Copmpose插件。

curl -fsSL https://higress.io/standalone/get-higress.sh | bash -s -- -c nacos://192.168.47.100:8848 --nacos-username=nacos --nacos-password=nacos -p <你的密码>

在这里插入图片描述

启动成功后,本机端口占用情况如下:

80端口:Higress 暴露,用于 HTTP 协议代理
443端口:Higress 暴露,用于 HTTPS 协议代理
15020端口:Higress 暴露,用于暴露 Prometheus 指标
8080端口:Higress 控制台 暴露,(admin/123456)

Higress命令
在这里插入图片描述

命令解释:

startup.sh : 启动Higress
shutdown.sh : 停止Higress
configure.sh : 配置nacos地址

访问Higress控制台

在浏览器中输入http://127.0.0.1:8080,使用用户名 admin 和安装时设置的密码登录 Higress 控制台。
在这里插入图片描述

创建网关微服务模块

创建子模块 jjy-order-higress

引入依赖包

 <!--   springboot依赖包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--   nacos依赖包  --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

编写配置文件
在resources文件夹下面创建application.yml文件。

spring:application:# 应用名字name: order-servicecloud:nacos:discovery:# Nacos注册中心的地址server-addr:  192.168.47.100:8848
server:port: 8006

编写主启动类
在com.jjy文件夹下面创建OrderHigressAppcation主启动类。

/*** 主启动类*/
@Slf4j
@EnableDiscoveryClient
@SpringBootApplication
public class OrderAppcation
{public static void main( String[] args ){SpringApplication.run(OrderAppcation.class,args);log.info("****************** 订单微服务启动成功 ***********");}
}

编写测试控制器

package com.jjy.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class IndexController {@GetMapping("/index")public String index(){return "hello  higress";}}

Higress路由配置

在这里插入图片描述
什么是路由

在微服务架构中,路由是一种用于管理和定向请求流量的重要机制。微服务架构将一个应用程序拆分成一组小型、独立的服务,每个服务专注于执行特定的业务功能。路由在这样的环境中起到了指导请求流向的作用。
在这里插入图片描述
安装Switchhosts
SwitchHosts是一款便捷且免费的软件,体积为8M左右,不会占用电脑过多的内存,并且默认就是绿色软件,带有简体中文界面,在windows7、xp与vista等系统中能够运行。

该软件主要带有两个功能:

切换hosts与编辑hosts。
在这里插入图片描述
设置域名
在这里插入图片描述
创建路由
配置支付服务路由规则。
在这里插入图片描述
设置路由策略
在这里插入图片描述
重写地址

在这里插入图片描述
请求验证
执行以下命令,验证测试路由可以正常工作:

# should output a JSON object containing request data 
curl http://www.it.com/payment/index

Higress策略配置-跨域配置

为什么会出现跨域问题

出于浏览器的同源策略限制。同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

当前页面url被请求页面url是否跨域原因
http://www.test.com/http://www.test.com/index.html同源(协议、域名、端口号相同)
http://www.test.com/https://www.test.com/index.html跨域协议不同(http/https)
http://www.test.com/http://www.baidu.com/跨域主域名不同(test/baidu)
http://www.test.com/http://blog.test.com/跨域子域名不同(www/blog)
http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同(8080/7001)

跨域问题演示
在resources中创建templates文件夹,在编写index页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body></body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>$.get("http://www.it.com/order/index",function(data,status){alert("Data: " + data );});
</script>
</html>

Higress解决如何允许跨域

CORS

  • 如何允许跨域,一种解决方法就是目的域告诉请求者允许什么来源域来请求,那么浏览器就会知道B域是否允许A域发起请求。
  • CORS(“跨域资源共享”(Cross-origin resource sharing))就是这样一种解决手段。

CORS使得浏览器在向目的域发起请求之前先发起一个OPTIONS方式的请求到目的域获取目的域的信息,比如获取目的域允许什么域来请求的信息。

Higress策略配置之什么是HTTP认证

概述
HTTP认证是一种用于保护Web应用程序的一种身份验证机制。它通过在HTTP请求的头部添加认证信息,来验证用户的身份和权限。HTTP认证可以用于保护敏感信息,限制访问某些资源,或者在访问某些操作之前要求用户提供凭据。

HTTP 基本认证

常见的验证方案包括
1、Basic Authentication(基本认证)
Basic认证是最常见的HTTP认证方式之一。在Basic认证中,客户端发送请求时,会在请求头中包含一个"Authorization"字段,该字段包含了经过Base64编码的用户名和密码。

2、Digest Authentication(摘要认证)
Digest认证是一种更安全的认证方式。在Digest认证中,服务器会向客户端发送一个随机数(称为"nonce"),客户端根据该随机数和用户密码计算一个摘要,并将其发送给服务器。服务器收到摘要后,会验证其有效性。Digest认证相对于Basic认证而言,更难以被中间人攻击截获密码。

3、Bearer Token Authentication(令牌认证)
Bearer认证是一种使用令牌(Token)进行身份验证的方式。在Bearer认证中,客户端在请求头中添加一个"Authorization"字段,该字段包含了一个令牌信息。服务器在接收到请求后,会验证令牌的有效性,并根据令牌来识别用户身份。

4、OAuth(开放授权)
OAuth认证是一种开放标准的身份验证协议,用于授权第三方应用程序访问用户资源。在OAuth认证中,用户可以通过授权服务器授权第三方应用程序访问自己的资源。这种方式可以避免用户将密码直接提供给第三方应用程序。

Higress策略配置-Basic 认证

在这里插入图片描述
Basic 概述
Basic 认证是HTTP 中非常简单的认证方式,因为简单,所以不是很安全,不过仍然非常常用。当一个客户端向一个需要认证的HTTP服务器进行数据请求时,,HTTP服务器会返回401状态码,要求客户端输入用户名和密码。用户输入用户名和密码后,用户名和密码会经过BASE64加密附加到请求信息中再次请求HTTP服务器,HTTP服务器会根据请求头携带的认证信息,决定是否认证成功及做出相应的响应。

在这里插入图片描述
功能说明

basic-auth插件实现了基于 HTTP Basic Auth 标准进行认证鉴权的功能

配置字段
全局配置

名称数据类型填写要求默认值描述
consumersarray of object必填-配置服务的调用者,用于对请求进行认证
global_authbool选填-若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制; 若不配置则仅当没有域名和路由配置时全局生效(兼容机制)

consumers中每一项的配置字段说明如下:

名称数据类型填写要求默认值描述
credentialstring必填-配置该consumer的访问凭证
namestring必填-配置该consumer的名称

域名和路由级配置

名称数据类型填写要求默认值描述
allowarray of string必填-对于符合匹配条件的请求,配置允许访问的consumer名称

注意:

  • 对于通过认证鉴权的请求,请求的header会被添加一个X-Mse-Consumer字段,用以标识调用者的名称。

配置示例
1、对特定路由或域名开启认证和鉴权

以下配置将对网关特定路由或域名开启 Basic Auth 认证和鉴权,注意凭证信息中的用户名和密码之间使用":"分隔,credential字段不能重复。

全局配置

consumers:
- credential: 'admin:123456'name: consumer1
- credential: 'guest:abc'name: consumer2
global_auth: false

路由级配置

对 route-a 和 route-b 这两个路由做如下配置:

allow: 
- consumer1

若是在控制台进行配置,此例指定的 route-aroute-b 即在控制台创建路由时填写的路由名称,当匹配到这两个路由时,将允许nameconsumer1的调用者访问,其他调用者不允许访问;此例指定的 *.example.comtest.com 用于匹配请求的域名,当发现域名匹配时,将允许nameconsumer2的调用者访问,其他调用者不允许访问。

测试配置

在这里插入图片描述
相关错误码

HTTP 状态码出错信息原因说明
401Request denied by Basic Auth check. No Basic Authentication information found.请求未提供凭证
401Request denied by Basic Auth check. Invalid username and/or password请求凭证无效
403Request denied by Basic Auth check. Unauthorized consumer请求的调用方无访问权限

什么是JWT认证

JWT (全称:Json Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。官方网址https://jwt.io/

传统的session认证
Session 的认证流程通常会像这样:
在这里插入图片描述

缺点:

安全性:CSRF攻击因为基于cookie来进行用户识别, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。
扩展性:对于分布式应用,需要实现 session 数据共享
性能:每一个用户经过后端应用认证之后,后端应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大,与REST风格不匹配。因为它在一个无状态协议里注入了状态。

JWT方式

在这里插入图片描述

优点:

  • 无状态
  • 适合移动端应用
  • 单点登录友好

JWT原理

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样

{"姓名": "张三","角色": "管理员","到期时间": "2030年7月1日0点0分"
}

注意:

用户与服务端通信的时候,都要发回这个 JSON
对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候会加上签名,服务器就不保存任何 session
数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。

JWT 结构
一个 JWT 实际上就是一个字符串,它由三部分组成:头部、载荷与签名。中间用点 . 分隔成三个部分。注意 JWT 内部是没有换行的。
在这里插入图片描述
头部 / header

JSON对象,描述 JWT 的元数据。其中 alg 属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ 属性表示这个令牌(token)的类型(type),统一写为 JWT。

{"alg": "HS256","typ": "JWT"
}

注意:

上面代码中,alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT然后将头部进行Base64编码构成了第一部分,Base64是一种用64个字符来表示任意二进制数据的方法,Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。

载荷 / Payload

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 指定七个默认字段供选择。除了默认字段之外,你完全可以添加自己想要的任何字段,一般用户登录成功后,就将用户信息存放在这里

iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
{"iss": "xxxxxxx","sub": "xxxxxxx","aud": "xxxxxxx","user": {'username': 'itbaizhan','userId': 1} 
}

签名 / Signature

  • 签名部分是对上面的 头部、载荷 两部分数据进行的数据签名
  • 为了保证数据不被篡改,则需要指定一个密钥,而这个密钥一般只有你知道,并且存放在服务端
  • 生成签名的代码一般如下:
// 其中secret 是密钥
String signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

JWT 的使用方式
在这里插入图片描述

流程:

客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在
localStorage。此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie
里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。

创建认证中心微服务

认证微服务模块
引入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.bitbucket.b_c</groupId><artifactId>jose4j</artifactId><version>0.7.0</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.18</version></dependency></dependencies>

创建配置文件
在resources文件夹下面创建application.yml文件。

spring:application:# 应用名字name: auth-servicecloud:nacos:discovery:# Nacos注册中心的地址server-addr:  192.168.47.100:8848
server:port: 8989

创建主启动类

@SpringBootApplication
@Slf4j
public class AuthApplication
{public static void main( String[] args ) throws JoseException {SpringApplication.run(AuthApplication.class,args);log.info("*****************  认证授权中心启动成功 **************");}
}

编写JWT工具类生成jwt

引入依赖

<dependency><groupId>org.bitbucket.b_c</groupId><artifactId>jose4j</artifactId><version>0.7.0</version>
</dependency>

生成公钥和私钥

RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);final String publicKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);final String privateKeyString = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);System.out.println(publicKeyString);System.out.println(privateKeyString);

生成token

 // 创建claims,这将是JWT的内容 B部分JwtClaims claims = new JwtClaims();// 谁创建了令牌并签署了它claims.setIssuer("abcd");// 令牌将被发送给谁claims.setAudience("Audience");// 令牌失效的时间长(从现在开始10分钟)claims.setExpirationTimeMinutesInTheFuture(10);// 令牌的唯一标识符claims.setGeneratedJwtId();// 当令牌被发布/创建时(现在)claims.setIssuedAtToNow();// 在此之前,令牌无效(2分钟前)claims.setNotBeforeMinutesInThePast(2);// 主题 ,是令牌的对象claims.setSubject("subject");// 可以添加关于主题的附加 声明/属性claims.setClaim("userId", userId);claims.setClaim("username", username);// JWT是一个JWS和/或一个带有JSON声明的JWE作为有效负载。// 在这个例子中,它是一个JWS,所以我们创建一个JsonWebSignature对象。JsonWebSignature jws = new JsonWebSignature();// JWS的有效负载是JWT声明的JSON内容jws.setPayload(claims.toJson());System.out.println(claims.toJson());PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privatekey)).getPrivateKey();// JWT使用私钥签署jws.setKey(privateKey);/** 设置关键ID(kid)头,因为这是一种礼貌的做法。 在这个例子中,我们只有一个键但是使用键ID可以帮助* 促进平稳的关键滚动过程*/jws.setKeyIdHeaderValue("keyId");// 在jw/jws上设置签名算法,该算法将完整性保护声明jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);/** 签署JWS并生成紧凑的序列化或完整的jw/JWS 表示,它是由三个点('.')分隔的字符串* 在表单头.payload.签名中使用base64url编码的部件 如果你想对它进行加密,你可以简单地将这个jwt设置为有效负载* 在JsonWebEncryption对象中,并将cty(内容类型)头设置为“jwt”。*/String jwt = jws.getCompactSerialization();// 现在你可以用JWT做点什么了。比如把它寄给其他的派对// 越过云层,穿过网络。System.out.println("JWT: " + jwt);return jwt;

编写JWT工具类解密Token

public static void checkJwt(String jwt) throws MalformedClaimException, JoseException {/** 使用JwtConsumer builder构建适当的JwtConsumer,它将 用于验证和处理JWT。 JWT的具体验证需求是上下文相关的, 然而,* 通常建议需要一个(合理的)过期时间,一个受信任的时间 发行人, 以及将你的系统定义为预期接收者的受众。* 如果JWT也被加密,您只需要提供一个解密密钥对构建器进行解密密钥解析器。*/PublicKey publicKey1 = new RsaJsonWebKey(JsonUtil.parseJson(publicKey)).getRsaPublicKey();JwtConsumer jwtConsumer = new JwtConsumerBuilder().setRequireExpirationTime().setAllowedClockSkewInSeconds(30) // 允许在验证基于时间的令牌时留有一定的余地,以计算时钟偏差。单位/秒.setRequireSubject() // 主题声明.setExpectedIssuer("Issuer") // JWT需要由谁来发布,用来验证 发布人.setExpectedAudience("Audience") // JWT的目的是给谁, 用来验证观众.setVerificationKey(publicKey1) // 用公钥验证签名 ,验证秘钥.setJwsAlgorithmConstraints( // 只允许在给定上下文中预期的签名算法,使用指定的算法验证new AlgorithmConstraints(ConstraintType.WHITELIST, // 白名单AlgorithmIdentifiers.RSA_USING_SHA256)).build(); // 创建JwtConsumer实例try {// 验证JWT并将其处理为jwtClaimsJwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
//          如果JWT失败的处理或验证,将会抛出InvalidJwtException。
//          希望能有一些有意义的解释(s)关于哪里出了问题。System.out.println("JWT validation succeeded! " + jwtClaims);} catch (InvalidJwtException e) {System.out.println("Invalid JWT! " + e);// 对JWT无效的(某些)特定原因的编程访问也是可能的// 在某些情况下,您是否需要不同的错误处理行为。// JWT是否已经过期是无效的一个常见原因if (e.hasExpired()) {System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());}// 或者观众是无效的if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID)) {System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());}}}

认证中心微服务颁发Token令牌

编写认证中心控制器
创建controller包,在controller里面新建AuthController接口。

@RestController
public class AuthController {@AutowiredSysLoginService sysLoginService;@PostMapping("login")public R<?> login(@RequestBody LoginBody form) throws MalformedClaimException, JoseException {return sysLoginService.login(form.getUsername(), form.getPassword());}}

编写统一结果返回集

package com.jjy.domian;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;/*** 统一结果返回集*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class R {// 状态码private int code;// 返回信息private String meg;// 数据private Object data;public static R fail(String meg){R r = new R();r.setCode(500);r.setMeg(meg);return r;}public static R ok(Object data){R r = new R();r.setCode(200);r.setMeg("sucess");r.setData(data);return r;}
}

登录业务层

package com.jjy.service;import com.alibaba.nacos.common.utils.StringUtils;
import com.itbaizhan.domian.LoginBodyDTO;
import com.itbaizhan.domian.R;
import com.itbaizhan.utils.JwtUtils;
import org.jose4j.lang.JoseException;
import org.springframework.stereotype.Service;@Service
public class SysLoginService {/*** 登录* @param loginBodyDTO* @return*/public R login(LoginBodyDTO loginBodyDTO) throws JoseException {// 1、用户名或者密码校验if (StringUtils.isEmpty(loginBodyDTO.getUsername()) || StringUtils.isEmpty(loginBodyDTO.getPassword()) ){return R.fail("用户名或者密码为空");}// 2、判断用户名和密码是否正确//TODO 数据库操作if (loginBodyDTO.getUsername().equals("admin")&& loginBodyDTO.getPassword().equals("123456")){// 颁发登录tokenString token = JwtUtils.sign(1001L, "admin");return R.ok(token);}else {return R.fail("用户名或者密码不对");}}}

JWT配置

在这里插入图片描述
基于Token的认证

很多对外开放的API需要识别请求者的身份,并据此判断所请求的资源是否可以返回给请求者。token就是一种用于身份验证的机制,基于这种机制,应用不需要在服务端保留用户的认证信息或者会话信息,可实现无状态、分布式的Web应用授权,为应用的扩展提供了便利。
在这里插入图片描述

业务流程:

1.客户端向API网关发起认证请求,请求中一般会携带终端用户的用户名和密码;
2.网关将请求直接转发给后端服务;
3.后端服务读取请求中的验证信息(比如用户名、密码)进行验证,验证通过后使用私钥生成标准的token,返回给网关;
4.网关将携带token的应答返回给客户端,客户端需要将这个token缓存到本地;
5.客户端向API网关发送业务请求,请求中携带token;
6.网关使用用户设定的公钥对请求中的token进行验证,验证通过后,将请求透传给后端服务;
7.后端服务进行业务处理后应答;
8.网关将业务应答返回给客户端。

功能说明
jwt-auth插件实现了基于JWT(JSON Web Tokens)进行认证鉴权的功能,支持从HTTP请求的URL参数、请求头、Cookie字段解析JWT,同时验证该Token是否有权限访问。

配置字段
全局配置

名称数据类型填写要求默认值描述
consumersarray of object必填-配置服务的调用者,用于对请求进行认证
global_authbool选填-若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制; 若不配置则仅当没有域名和路由配置时全局生效(兼容机制)

consumers中每一项的配置字段说明如下:

名称数据类型填写要求默认值描述
namestring必填-配置该consumer的名称
jwksstring必填-https://www.rfc-editor.org/rfc/rfc7517 指定的json格式字符串,是由验证JWT中签名的公钥(或对称密钥)组成的Json Web Key Set
issuerstring必填-JWT的签发者,需要和payload中的iss字段保持一致
claims_to_headersarray of object选填-抽取JWT的payload中指定字段,设置到指定的请求头中转发给后端
from_headersarray of object选填[{“name”:“Authorization”,“value_prefix”:"Bearer "}]从指定的请求头中抽取JWT
from_paramsarray of string选填access_token从指定的URL参数中抽取JWT
from_cookiesarray of string选填-从指定的cookie中抽取JWT
clock_skew_secondsnumber选填60校验JWT的exp和iat字段时允许的时钟偏移量,单位为秒
keep_tokenbool选填true转发给后端时是否保留JWT

注意:
只有当from_headers,from_params,from_cookies均未配置时,才会使用默认值

from_headers 中每一项的配置字段说明如下:

名称数据类型填写要求默认值描述
namestring必填-抽取JWT的请求header
value_prefixstring必填-对请求header的value去除此前缀,剩余部分作为JWT

claims_to_headers 中每一项的配置字段说明如下:

名称数据类型填写要求默认值描述
claimstring必填-JWT
headerstring必填-从payload取出字段的值设置到这个请求头中,转发给后端
overridebool选填truetrue时,存在同名请求头会进行覆盖;false时,追加同名请求头

域名和路由级配置

名称数据类型填写要求默认值描述
allowarray of string必填-对于符合匹配条件的请求,配置允许访问的consumer名称

注意:

对于通过认证鉴权的请求,请求的header会被添加一个X-Mse-Consumer字段,用以标识调用者的名称。

配置示例

1、配置全局策略

在插件市场中找到JWT Auth进行策略配置。

consumers:
- issuer: "abcd"jwks: |{"keys": [{"kty": "RSA","n": "u8SyxKf2kLkmOKOU-mcbXQmacQDCPtxfMGKzYx6HWaGcCFbIrFDubGIWhe3GRP5uQqXekqwDtiqurdGfUzOLSSLfe7bmCmEgntNbF9bgk8lZUhzszmb4sGk6VK4YiOiTWGYWn_7jyKyF_OXEpXY4C3WWWsZwQfLPNUYfVZE76o1MXT9F3622RhLSPOFVqJYL6RlzllvNc2PdfzVEBnFU4wKszT0n9J8ZrNAnlNUxOXi7Y78fLqQks60ERznZwytwB8krydQGkjH9y9pf70QFJW228mUxXHnPhG87Gi2eE62TardkBCvQcm4TJlEB5dnmhFYFhRkAR6IznUAjtkFZIw","e": "AQAB","use": "sig","kid": "keyId","alg": "RS256"}]}name: "consumer1"
global_auth: false

2、配置路由级别

开启order-service微服务权限认证。

allow:
- "consumer1"

测试认证中心
1、生成用户登录token令牌

image-20231117140402178

2、测试token令牌

image-20231117140504500

Key 认证

在这里插入图片描述
功能说明
key-auth插件实现了基于 API Key 进行认证鉴权的功能,支持从 HTTP 请求的 URL 参数或者请求头解析 API Key,同时验证该 API Key 是否有权限访问。

配置字段
全局配置

名称数据类型填写要求默认值描述
consumersarray of object必填-配置服务的调用者,用于对请求进行认证
keysarray of string必填-API Key 的来源字段名称,可以是 URL 参数或者 HTTP 请求头名称
in_queryboolin_query 和 in_header 至少有一个为 truetrue配置 true 时,网关会尝试从 URL 参数中解析 API Key
in_headerboolin_query 和 in_header 至少有一个为 truetrue配置 true 时,网关会尝试从 HTTP 请求头中解析 API Key
global_authbool选填-若配置为true,则全局生效认证机制; 若配置为false,则只对做了配置的域名和路由生效认证机制; 若不配置则仅当没有域名和路由配置时全局生效(兼容机制)

consumers中每一项的配置字段说明如下:

名称数据类型填写要求默认值描述
credentialstring必填-配置该consumer的访问凭证
namestring必填-配置该consumer的名称

域名和路由级配置

名称数据类型填写要求默认值描述
allowarray of string必填-对于符合匹配条件的请求,配置允许访问的consumer名

注意:
对于通过认证鉴权的请求,请求的header会被添加一个X-Mse-Consumer字段,用以标识调用者的名称。

配置示例
1、对特定路由或域名开启

以下配置将对网关特定路由或域名开启 Key Auth 认证和鉴权,注意credential字段不能重复

全局配置

consumers:
- credential: 2bda943c-ba2b-11ec-ba07-00163e1250b5name: consumer1
- credential: c8c8e9ca-558e-4a2d-bb62-e700dcc40e35name: consumer2
keys:
- apikey
in_query: true
global_auth: false

路由级配置

对 route-a 和 route-b 这两个路由做如下配置:

allow: 
- consumer1
- ```
对 *.exmaple.com 和 test.com 在这两个域名做如下配置:
```yml
allow:
- consumer2

请求未提供 API Key,返回401

curl  http://xxx.hello.com/test

相关错误码

HTTP 状态码出错信息原因说明
401No API key found in request请求未提供 API Key
401Request denied by Key Auth check. Invalid API key不允许当前 API Key 访问
403Request denied by Basic Auth check. Unauthorized consumer请求的调用方无访问权限

请求屏蔽

在这里插入图片描述
功能说明
request-block插件实现了基于 URL、请求头等特征屏蔽 HTTP 请求,可以用于防护部分站点资源不对外部暴露。

配置字段

名称数据类型填写要求默认值描述
block_urlsarray of string选填,block_urls,block_headers,block_bodies 中至少必填一项-配置用于匹配需要屏蔽 URL 的字符串
block_headersarray of string选填,block_urls,block_headers,block_bodies 中至少必填一项-配置用于匹配需要屏蔽请求 Header 的字符串
block_bodiesarray of string选填,block_urls,block_headers,block_bodies 中至少必填一项-配置用于匹配需要屏蔽请求 Body 的字符串
blocked_codenumber选填403配置请求被屏蔽时返回的 HTTP 状态码
blocked_messagestring选填-配置请求被屏蔽时返回的 HTTP 应答 Body
case_sensitivebool选填true配置匹配时是否区分大小写,默认区分

配置示例
1、屏蔽请求 url 路径

block_urls:
- swagger.html
- foo=bar
case_sensitive: false

根据该配置,下列请求将被禁止访问:

curl http://example.com?foo=Bar
curl http://exmaple.com/Swagger.html

2、屏蔽请求 header

block_headers:
- example-key
- example-value

根据该配置,下列请求将被禁止访问:

curl http://example.com -H 'example-key: 123'
curl http://exmaple.com -H 'my-header: example-value'

3、屏蔽请求 body

block_bodies:
- "hello world"
case_sensitive: false

根据该配置,下列请求将被禁止访问:

curl http://example.com -d 'Hello World'
curl http://exmaple.com -d 'hello world'

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力
在这里插入图片描述

相关文章:

8.15日学习打卡---Spring Cloud Alibaba(三)

8.15日学习打卡 目录&#xff1a; 8.15日学习打卡为什么需要服务网关Higress是什么安装DockerCompose部署Higress创建网关微服务模块Higress路由配置Higress策略配置-跨域配置Higress解决如何允许跨域Higress策略配置之什么是HTTP认证Higress策略配置-Basic 认证什么是JWT认证J…...

2024下半年EI学术会议一览表

2024下半年将举办多个重要的EI学术会议&#xff0c;涵盖了从机器视觉、图像处理与影像技术到感知技术、绿色通信、计算机、大数据与人工智能等多个领域。 2024下半年EI学术会议一览表 第二届机器视觉、图像处理与影像技术国际会议&#xff08;MVIPIT 2024&#xff09;将于2024…...

【海奇HC-RTOS平台E100-问题点】

海奇HC-RTOS平台E100-问题点 ■ btn 没有添加到group中 &#xff0c;怎么实现的事件的■ 屏幕是1280*720, UI是1024*600,是否修改UI■ hc15xx-db-e100-v10-hcdemo.dtb 找不到■ 触摸屏驱动 能否给个实例■ 按键驱动■ __initcall(projector_auto_start)■ source insigt4.0 #if…...

性能测试之Mysql数据库调优

一、前言 性能调优前提&#xff1a;无监控不调优&#xff0c;对于mysql性能的监控前几天有文章提到过&#xff0c;有兴趣的朋友可以去看一下 二、Mysql性能指标及问题分析和定位 1、我们在监控图表中关注的性能指标大概有这么几个&#xff1a;CPU、内存、连接数、io读写时间…...

使用 RestHighLevelClient 进行 Elasticsearch 高亮查询及解析

在搜索引擎中&#xff0c;高亮显示查询关键字是一个提升用户体验的功能&#xff0c;它可以帮助用户更快地定位到相关信息。Elasticsearch 支持在搜索结果中对匹配的文本进行高亮显示。本文将介绍如何在 Java 应用程序中使用 Elasticsearch 的 RestHighLevelClient 执行高亮查询…...

Java基础入门15:算法、正则表达式、异常

算法&#xff08;选择排序、冒泡排序、二分查找&#xff09; 选择排序 每轮选择当前位置&#xff0c;开始找出后面的较小值与该位置交换。 选择排序的关键&#xff1a; 确定总共需要选择几轮&#xff1a;数组的长度-1。 控制每轮从以前位置为基准&#xff0c;与后面元素选择…...

SpringBoot响应式编程 WebFlux入门教程

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f525; 微信&#xff1a;zsqtcyw 联系我领取学习资料 …...

LeetCode 383. 赎金信

题目 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入&…...

python绘制电路图

要在 Python 中实现电路图&#xff0c;你可以使用一些专门的库来创建和可视化电路图。一个常用的库是 schemdraw&#xff0c;它可以用来绘制电路图&#xff0c;并支持多种电气组件和符号。 下面是一个使用 schemdraw 库绘制简单电路图的示例&#xff1a; 安装 schemdraw 库&am…...

Vue3 Suspense 和 defineAsyncComponent 结合使用方法

Suspense&#xff1a;用于协调对组件树中嵌套的异步依赖的处理。 defineAsyncComponent&#xff1a;定义一个异步组件&#xff0c;它在运行时是懒加载的。参数可以是一个异步加载函数&#xff0c;或是对加载行为进行更具体定制的一个选项对象。 异步组件的好处&#xff1a;使…...

GitHub中Codespace怎么使用;LLM模拟初始化;MLP:全连接神经网络的并行执行

目录 PyUnit unittest是什么 unittest怎么使用 GitHub中Codespace怎么使用 测试常用功能 LLM模拟初始化 参数解释 类属性设置 总结 MLP:全连接神经网络的并行执行 假设 代码解释 注意事项 PyUnit unittest是什么 unittest是Python的内置单元测试框架,原名PyUn…...

【rh】rh项目部署

【fastadmin】 1、项目先clone到本地&#xff0c;其中web为h5前端使用(gitclone后&#xff0c;把web内容放进去再提交)&#xff0c;其余为项目后端使用 2、安装本地环境&#xff0c;项目跑起来&#xff0c;步骤如下&#xff1a; 1&#xff09;查春.git 和 composer,json 版本信…...

VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection

VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection Abstract 摘要部分&#xff0c;作者首先指出了3D点云中目标检测的重要性&#xff0c;在自动驾驶导航、家政机器人以及增强现实和虚拟现实等多个领域有重要的作用。然后&#xff0c;提到了现有方法的…...

结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/141122350 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

LLM 量化算法AutoRound 0.3 发布及原理浅析

这里写自定义目录标题 AutoRound V0.3 特性原理浅析其他工作AutoRound 原理 AutoRound&#xff08;https://github.com/intel/auto-round&#xff09;在Llama3.1-8B-Instruct上效果明显优于AWQ/GPTQ等方法&#xff0c;在10个任务的平均准确率上我们以63.93%由于AWQ的63.15%和GP…...

汽车免拆诊断案例 | 2013款北京现代悦动车发动机偶尔无法起动

故障现象 一辆2013款北京现代悦动车&#xff0c;搭载G4FC发动机&#xff0c;累计行驶里程约为13.9万km。车主反映&#xff0c;发动机偶尔无法起动着机&#xff0c;断开点火开关&#xff0c;等待一会儿又可以起动着机。 故障诊断 接车后反复试车&#xff0c;当发动机无法起动着…...

React、AntD,封装动态表单

在React中使用Ant Design(简称AntD)来封装动态表单是一个常见的需求,特别是在需要灵活配置表单字段的场景下。以下是一个基本的步骤和示例代码,展示如何使用React和AntD来封装一个动态表单。 步骤 1: 安装必要的库 首先,确保你的项目中已经安装了react和antd。如果还没有…...

【Linux基础】Linux中的开发工具(3)--make/makefile和git的使用

目录 前言一&#xff0c;Linux项目自动化构建工具-make/makefile1. 背景2. 依赖关系和依赖方法3. 项目清理4. 使用方法和原理5. .PHONY的作用6. makefile中符号的使用 二&#xff0c;进度条的实现1. 理解回车换行2. 理解行缓冲区3. 版本14. 版本2 三&#xff0c;Linux上git的使…...

过滤了字母、数字、_、$的webshell命令执行技巧

目录 对于php5以上首先要解决的问题有 解决技巧 1.code长度小于35位 2.没有字母、数字、_ 、$ 3.怎么把文件放进服务器 4.怎么执行文件里面的内容 1.执行Linux命令 2.执行文件里面的shell命令 5.构造完整的code参数 6.我们还可以通过修改文件里面shell命令&#xff0c;…...

python-A+B again

[题目描述] 小理有一个非常简单的问题给你&#xff0c;给你两个整数 A 和 B&#xff0c;你的任务是计算 AB。输入格式&#xff1a; 输入共 2∗T1 行。 输入的第一行包含一个整数 T 表示测试实例的个数&#xff0c;然后 2∗T 行&#xff0c;分别表示 A 和 B 两个正整数。注意整数…...

C语言—函数递归

一、递归概念 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃⼰调⽤⾃⼰。下面举一个例子&#xff1a; 上述就是⼀个简单的递归程序&#xff0c;只不过上⾯的递归只是为了演⽰递归的基本形式&#xff0c;不是为了解决问题&#xff0c;代码最终…...

结构开发笔记(四):solidworks软件(三):绘制36x36方块摄像头示意体

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/141187797 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

【机器学习】Caltech-101的基本概念和使用方法以及Caltech-101和ImageNet的联系和区别

引言 Caltech-101数据集是一个广泛用于对象识别任务的数据库&#xff0c;它包含了大约9,000张图像&#xff0c;这些图像来自101个不同的对象类别。每个类别包含的图像数量大约在40到800张之间&#xff0c;大多数类别大约有50张图像。图像的分辨率大致为300200像素 文章目录 引言…...

mysql Ubuntu安装与远程连接配置

一、安装&#xff08;Ubuntu22环境安装mysql8&#xff09; 这里使用Xshell链接Ubuntu和mysql windows进行操作&#xff0c;特别提醒&#xff1a;安装之前建议对Ubuntu快照处理备份&#xff0c;避免安装中出错导致Ubuntu崩溃。 查看是否安装的有可以用指令&#xff1a;ps -ef|…...

c语言中比较特殊的输入格式

目录 一.%[ ] 格式说明符 1.基本用法 (1)读取字母字符: (2)读取数字字符: (3)读取所有字符直到遇到空格: (4)读取直到换行符: 2.使用范围和组合: 3.^ 取反操作 4.注意事项 (1). 字符范围的正确表示 (2). 避免字符集中的特殊字符冲突 (3).避免空字符集 (4). 输入长…...

远程命令行控制SSH

第一次接触SSH是ROS小车作为服务端&#xff0c;通过ubuntu电脑客户端访问。因为机器人接键盘和屏幕操作起来不方便&#xff0c;所以使用SSH进行连接&#xff0c;方便对小车的操作。 1.服务端安装 打开终端查看ssh是否安装 sudo service ssh status 如果未安装 sudo apt upd…...

钢铁百科:A572Gr60和SA572Gr60材质分析、A572Gr60和SA572Gr60简介

A572Gr60和SA572Gr60是两种常用的结构钢板&#xff0c;它们在材质、执行标准、化学成分、力学性能、交货状态、应用范围和常用规格方面有所不同。 材质&#xff1a; A572Gr60&#xff1a;属于美国材料与试验协会&#xff08;ASTM&#xff09;标准下的A572系列高性能结构钢&…...

一次sql请求,返回分页数据和总条数

日常搬砖&#xff0c;总少不了需要获取分页数据和总行数。 一直以来的实践是编码两次sql请求&#xff0c;分别拉分页数据和totalCount。 最近我在思考&#xff1a; 常规实践为什么不是 在一次sql请求中中执行多次sql查询或多次更新&#xff0c;显而易见的优势&#xff1a; ① 能…...

2.5 pyautogui 实现微信自动回复

第四节&#xff1a;实战微信自动回复 课程目标 学习如何通过pyautogui完成微信自动回复 课程内容 编码实现 import pyautogui as pg import time from pyautogui import ImageNotFoundException import pyperclip from cnocr import CnOcr import random ocr CnOcr() msg…...

观存储历史,论数据未来

数据存储 这几天我反复观看了腾讯云社区的《中国数据库前世今生》纪录片&#xff0c;每次的感受都大相径庭。以下是我在这段时间里对纪录片的两个不同感想&#xff0c;希望感兴趣的小伙伴们也能去观看一番。 一个是关于国产数据库的发展趋势的探讨&#xff1a;https://blog.c…...