• SpringCloudAlibaba:4.3云原生网关higress的JWT 认证


    概述

    简介

    JWT是一种用于双方之间传递安全信息的简洁的、URL安全的声明规范。

    定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息,特别适用于分布式站点的单点登录(SSO)场景

    session认证的缺点

    1.安全性:CSRF攻击因为基于cookie来进行用户识别, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

    2.扩展性:对于分布式应用,需要实现 session 数据共享

    3.性能:每一个用户经过后端应用认证之后,后端应用都要在服务端做一次记录,以方便用户下次请求的鉴别, 通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大

    JWT的优点

    1.无状态

    2.适合移动端应用

    3.单点登录友好

    流程

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

    编写JWT的流程

    第一步:头部header

    JSON对象,描述 JWT 的元数据 { "alg": "HS256", "typ": "JWT" }

    alg属性表示签名的算法,默认是 HMAC SHA256(写成 HS256 )

    typ属性表示这个令牌(token)的类型(type),统一写为 JWT

    第二步:载荷payload

    { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }

    内容又可以分为3中标准:标准中注册的声明/公共的声明/私有的声明

    1.payload-标准中注册的声明 (建议但不强制使用):

    iss: jwt签发者

    sub: jwt所面向的用户

    aud: 接收jwt的一方

    exp: jwt的过期时间,这个过期时间必须要大于签发时间

    nbf: 定义在什么时间之前,该jwt都是不可用的.

    iat: jwt的签发时间 jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 2.payload-公共的声明 : 公共的声明可以添加任何的信息。一般这里我们会存放一下用户的基本信息(非敏感信息)

    3.payload-私有的声明 : 私有声明是提供者和消费者所共同定义的声明。需要注意的是,不要存放敏感信息!!!

    第三步:签证signature

    签证的值是对头部和载荷进行base64UrlEncode后使用指定算法签名生成【私钥签名,到时候用公钥解密】

    1.放入头部

    2.放入载荷

    3.使用私【公】钥签署

    4.设置签名算法

    如:以默认HS256为例,指定一个密钥(secret),就会按照如下公式生成

    HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret, )

    第四步

    算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户

    示例

    依赖

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <parent>
    6. <artifactId>java_sc_alibaba</artifactId>
    7. <groupId>jkw.life</groupId>
    8. <version>1.0-SNAPSHOT</version>
    9. </parent>
    10. <modelVersion>4.0.0</modelVersion>
    11. <artifactId>test-higress-jwt-8007</artifactId>
    12. <dependencies>
    13. <!-- nacos-discovery -->
    14. <dependency>
    15. <groupId>com.alibaba.cloud</groupId>
    16. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    17. </dependency>
    18. <!-- SpringMVC-->
    19. <dependency>
    20. <groupId>org.springframework.boot</groupId>
    21. <artifactId>spring-boot-starter-web</artifactId>
    22. </dependency>
    23. <!-- JWT-->
    24. <dependency>
    25. <groupId>org.bitbucket.b_c</groupId>
    26. <artifactId>jose4j</artifactId>
    27. <version>0.7.0</version>
    28. </dependency>
    29. </dependencies>
    30. </project>

    application.yml

    1. server:
    2. port: 8007
    3. spring:
    4. application:
    5. name: test-higress-jwt-8007
    6. cloud:
    7. nacos:
    8. discovery:
    9. # 配置 nacos注册中心地址
    10. server-addr: 192.168.66.103:8848

    启动类

    1. package jkw;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    6. @Slf4j
    7. @EnableDiscoveryClient
    8. @SpringBootApplication
    9. public class Main8007 {
    10. public static void main(String[] args) {
    11. SpringApplication.run(Main8007.class, args);
    12. log.info("************** 服务提供者 8001 启动成功 ************");
    13. }
    14. }

    工具类【utils.JWTUtil】

    1. package jkw.utils;
    2. import org.jose4j.json.JsonUtil;
    3. import org.jose4j.jwa.AlgorithmConstraints;
    4. import org.jose4j.jwk.JsonWebKey;
    5. import org.jose4j.jwk.RsaJsonWebKey;
    6. import org.jose4j.jwk.RsaJwkGenerator;
    7. import org.jose4j.jws.AlgorithmIdentifiers;
    8. import org.jose4j.jws.JsonWebSignature;
    9. import org.jose4j.jwt.JwtClaims;
    10. import org.jose4j.jwt.MalformedClaimException;
    11. import org.jose4j.jwt.consumer.ErrorCodes;
    12. import org.jose4j.jwt.consumer.InvalidJwtException;
    13. import org.jose4j.jwt.consumer.JwtConsumer;
    14. import org.jose4j.jwt.consumer.JwtConsumerBuilder;
    15. import org.jose4j.lang.JoseException;
    16. import java.security.PrivateKey;
    17. import java.security.PublicKey;
    18. /**
    19. * JWT工具类
    20. */
    21. public class JWTUtil {
    22. public static void main(String[] args) throws JoseException {
    23. RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
    24. //生成公钥
    25. //{"kty":"RSA","n":"ziX1yaqbQWGGto1B4NxvmYifUTSigM2LEN0KubXoxt7t9Nz9NaqES4Y36e_v_DhT_v0mKC74pReTWcDVSXZE49jFWphBNlcsnWOsjMlntVlZ_rOQyLZEMhcqshQVvBU8UPFoc77UYBddAjnnShdrSsP5e9qMeMAJVsRCEJZ3Y1IkwRmUGThhmqXNGn1UEhtMSrXDewkre7AWNVkixky7SV-0WhdA6QrEPtLfXoXBQseO2QgRAA73Gc7rs1hF89lKphcBx_mtngonAltNtGGuDhXriBCnt_zuUx8Bt7S-XlECxjSFtHbWKsgOuWTXxMIOVMHoerinsDP1AKmIqPo5xw","e":"AQAB"}
    26. final String publicKey = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
    27. System.out.println(publicKey);
    28. //生成私钥
    29. //{"kty":"RSA","n":"ziX1yaqbQWGGto1B4NxvmYifUTSigM2LEN0KubXoxt7t9Nz9NaqES4Y36e_v_DhT_v0mKC74pReTWcDVSXZE49jFWphBNlcsnWOsjMlntVlZ_rOQyLZEMhcqshQVvBU8UPFoc77UYBddAjnnShdrSsP5e9qMeMAJVsRCEJZ3Y1IkwRmUGThhmqXNGn1UEhtMSrXDewkre7AWNVkixky7SV-0WhdA6QrEPtLfXoXBQseO2QgRAA73Gc7rs1hF89lKphcBx_mtngonAltNtGGuDhXriBCnt_zuUx8Bt7S-XlECxjSFtHbWKsgOuWTXxMIOVMHoerinsDP1AKmIqPo5xw","e":"AQAB","d":"LclImg4GhbL_lLQzGZpcPyGVIRgrr6f3ZztxEmZQ2TrSZzxeEPlagNvCt3bPOpnYLh5Tx0EHgMOHuruVo8dc7a5Lxx9h_IvIIPzuaiahninGT0fatHmnE-kJVpwXZ7rftqqnpG2SBfWqdsAdmtswvV5hnxyfboJYkKjuc3i385r4s1s0pTZp33C6adHWB7B_dyVouQyjKQfUu_hToD32omJcTmJNcsTIKOR2Lztx-2Dzc4V99-3qDVbwXbBTfle_1tIeHYtSOsaBqVWpqdPOXSw5D4QuFjqUIXEVhIpTw5qNIejlAJ6wSHKUpU7DRm7t7Yl3yH5TqGr1WRB5eA6cYQ","p":"91hbnLKTPYeZrIq77YoSO0mzu8Q-rdJOv9Nece_oTL9zxLyV0JdzBWRkCUEqoaWSb6j1oeXC1qliHOYyls3Jf1e7bjFvJVedPGRtmEBWW_-nRFrIIYKswcco5_qRy4fHtOdNqwObyO1-8hLlu46kU5pxujlHKz0DAclLVOG8Wjs","q":"1VySxagoE5SDnhb2PDmNRF1uXrFHo1bg62KqAfCaws-MtNxaC9dtfBAHKH-s2QEfMYpiLv1i0IkronhvUZug0L-DzLemdwCyV98naaBElMzkTsC2hZpkmqR95HTACFSzpC5KRspl1ZvIxq-U-n5BY9asqpkhoyn7dCpkRy9tWeU","dp":"R5SEfqaXQdk6Odq0ZBvvBsVfhFlYokkYjR8IWATLv1owkKDa4lDR8p-I67y2L62Q4UuOOloZtrGyORbNUSMgyv-CuHMJ7U6brFyL8uG7nEgyCfATts7wW-vdBLVY-APFYa8GpRUYQl-ouzmIzmyLVb5-ZxwoYnT3p86vRFNHhP0","dq":"i9qIYoNc8aixtVh7wvI-hQdxJySxPoHeIKyln2vlJbkCFDMz2vs0ytN-va8iz4OKvOBmh0KUGPkw3uhun2GRwgMnE3N17B9Kx4qAvR3OlnLPXEe53E1dkHguBSf6D_vlXMLy8QAOTDw3GPVSg_dqSVUYDSMfB2KnbnezD24pEXk","qi":"kSGhqTuRjKESkVeJdWipF9kFy5-1p6T2Ym-S74PVVjBChuasvkkJtfLppw-yb0fX504TjoLDJIvYNp2fDY3Gv8CVr_W4cQjViEONrbGspzQTZmPAVEH0TiovFZ7z_KNp3P5Pl6JXMhOwxKsEM3hGj8IL6-4Bkh9-wOHG1mOi4sQ"}
    30. final String privateKey = rsaJsonWebKey.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
    31. System.out.println(privateKey);
    32. }
    33. //公钥
    34. private static final String publicKeyString = "{\"kty\":\"RSA\",\"n\":\"ziX1yaqbQWGGto1B4NxvmYifUTSigM2LEN0KubXoxt7t9Nz9NaqES4Y36e_v_DhT_v0mKC74pReTWcDVSXZE49jFWphBNlcsnWOsjMlntVlZ_rOQyLZEMhcqshQVvBU8UPFoc77UYBddAjnnShdrSsP5e9qMeMAJVsRCEJZ3Y1IkwRmUGThhmqXNGn1UEhtMSrXDewkre7AWNVkixky7SV-0WhdA6QrEPtLfXoXBQseO2QgRAA73Gc7rs1hF89lKphcBx_mtngonAltNtGGuDhXriBCnt_zuUx8Bt7S-XlECxjSFtHbWKsgOuWTXxMIOVMHoerinsDP1AKmIqPo5xw\",\"e\":\"AQAB\"}";
    35. //私钥
    36. private static final String privateKeyString = "{\"kty\":\"RSA\",\"n\":\"ziX1yaqbQWGGto1B4NxvmYifUTSigM2LEN0KubXoxt7t9Nz9NaqES4Y36e_v_DhT_v0mKC74pReTWcDVSXZE49jFWphBNlcsnWOsjMlntVlZ_rOQyLZEMhcqshQVvBU8UPFoc77UYBddAjnnShdrSsP5e9qMeMAJVsRCEJZ3Y1IkwRmUGThhmqXNGn1UEhtMSrXDewkre7AWNVkixky7SV-0WhdA6QrEPtLfXoXBQseO2QgRAA73Gc7rs1hF89lKphcBx_mtngonAltNtGGuDhXriBCnt_zuUx8Bt7S-XlECxjSFtHbWKsgOuWTXxMIOVMHoerinsDP1AKmIqPo5xw\",\"e\":\"AQAB\",\"d\":\"LclImg4GhbL_lLQzGZpcPyGVIRgrr6f3ZztxEmZQ2TrSZzxeEPlagNvCt3bPOpnYLh5Tx0EHgMOHuruVo8dc7a5Lxx9h_IvIIPzuaiahninGT0fatHmnE-kJVpwXZ7rftqqnpG2SBfWqdsAdmtswvV5hnxyfboJYkKjuc3i385r4s1s0pTZp33C6adHWB7B_dyVouQyjKQfUu_hToD32omJcTmJNcsTIKOR2Lztx-2Dzc4V99-3qDVbwXbBTfle_1tIeHYtSOsaBqVWpqdPOXSw5D4QuFjqUIXEVhIpTw5qNIejlAJ6wSHKUpU7DRm7t7Yl3yH5TqGr1WRB5eA6cYQ\",\"p\":\"91hbnLKTPYeZrIq77YoSO0mzu8Q-rdJOv9Nece_oTL9zxLyV0JdzBWRkCUEqoaWSb6j1oeXC1qliHOYyls3Jf1e7bjFvJVedPGRtmEBWW_-nRFrIIYKswcco5_qRy4fHtOdNqwObyO1-8hLlu46kU5pxujlHKz0DAclLVOG8Wjs\",\"q\":\"1VySxagoE5SDnhb2PDmNRF1uXrFHo1bg62KqAfCaws-MtNxaC9dtfBAHKH-s2QEfMYpiLv1i0IkronhvUZug0L-DzLemdwCyV98naaBElMzkTsC2hZpkmqR95HTACFSzpC5KRspl1ZvIxq-U-n5BY9asqpkhoyn7dCpkRy9tWeU\",\"dp\":\"R5SEfqaXQdk6Odq0ZBvvBsVfhFlYokkYjR8IWATLv1owkKDa4lDR8p-I67y2L62Q4UuOOloZtrGyORbNUSMgyv-CuHMJ7U6brFyL8uG7nEgyCfATts7wW-vdBLVY-APFYa8GpRUYQl-ouzmIzmyLVb5-ZxwoYnT3p86vRFNHhP0\",\"dq\":\"i9qIYoNc8aixtVh7wvI-hQdxJySxPoHeIKyln2vlJbkCFDMz2vs0ytN-va8iz4OKvOBmh0KUGPkw3uhun2GRwgMnE3N17B9Kx4qAvR3OlnLPXEe53E1dkHguBSf6D_vlXMLy8QAOTDw3GPVSg_dqSVUYDSMfB2KnbnezD24pEXk\",\"qi\":\"kSGhqTuRjKESkVeJdWipF9kFy5-1p6T2Ym-S74PVVjBChuasvkkJtfLppw-yb0fX504TjoLDJIvYNp2fDY3Gv8CVr_W4cQjViEONrbGspzQTZmPAVEH0TiovFZ7z_KNp3P5Pl6JXMhOwxKsEM3hGj8IL6-4Bkh9-wOHG1mOi4sQ\"}";
    37. /**
    38. * 生成token
    39. *
    40. * @param userId 用户id
    41. * @param username 用户名
    42. * @return
    43. */
    44. public static String sign(Long userId, String username) throws JoseException {
    45. // 第一步:载荷payload
    46. JwtClaims claims = new JwtClaims();
    47. // 注册的声明 1.jwt签发者
    48. claims.setIssuer("user");
    49. // 注册的声明 2.jwt所面向的用户
    50. claims.setSubject("subject");
    51. // 注册的声明 3.接收jwt的一方
    52. claims.setAudience("Audience");
    53. // 注册的声明 4.jwt的过期时间,这个过期时间必须要大于签发时间【从现在开始10分钟】
    54. claims.setExpirationTimeMinutesInTheFuture(10000);
    55. // 注册的声明 5.定义在什么时间之前,该jwt都是不可用的【2分钟前】
    56. claims.setNotBeforeMinutesInThePast(2);
    57. // 注册的声明 6.jwt的签发时间
    58. claims.setIssuedAtToNow();
    59. // 注册的声明 7.jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
    60. claims.setGeneratedJwtId();
    61. // 公共的声明:可可以添加任何的信息,一般这里我们会存放一下用户的基本信息
    62. claims.setClaim("userId", userId);
    63. claims.setClaim("username", username);
    64. // 第二步:签证signature:其值是对头部header和载荷payload进行base64UrlEncode后使用指定算法签名生成
    65. JsonWebSignature jws = new JsonWebSignature();
    66. // 1.放入头部
    67. jws.setKeyIdHeaderValue("keyId");
    68. // 2.放入载荷
    69. jws.setPayload(claims.toJson());
    70. // 3.使用私钥签名
    71. PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyString)).getPrivateKey();
    72. jws.setKey(privateKey);
    73. // 4.设置签名算法
    74. jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
    75. //第三步:算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户
    76. String jwt = jws.getCompactSerialization();
    77. return jwt;
    78. }
    79. /**
    80. * 验证jwt
    81. *
    82. * @param jwt
    83. */
    84. public static void checkJwt(String jwt) throws MalformedClaimException, JoseException {
    85. //1.引入公钥,使用公钥对私钥的签名解密
    86. PublicKey publicKey = new RsaJsonWebKey(JsonUtil.parseJson(publicKeyString)).getRsaPublicKey();
    87. //2.使用JwtConsumer解密
    88. JwtConsumer jwtConsumer = new JwtConsumerBuilder().setRequireExpirationTime()
    89. .setAllowedClockSkewInSeconds(30) // 允许在验证基于时间的令牌时留有一定的余地,以计算时钟偏差,单位/
    90. .setRequireSubject() // 主题声明
    91. .setExpectedIssuer("user") // 验证 jwt签发者
    92. .setExpectedAudience("Audience") // 验证 接收jwt的一方
    93. .setVerificationKey(publicKey) // 用公钥验证签名 ,验证私钥
    94. .setJwsAlgorithmConstraints( // 使用生成jwt的签名算法解密
    95. new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, // 白名单
    96. AlgorithmIdentifiers.RSA_USING_SHA256))
    97. .build();
    98. try {
    99. // 验证JWT并将其处理为jwtClaims
    100. JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
    101. //如果JWT失败的处理或验证,将会抛出InvalidJwtException,希望能有一些有意义的解释关于哪里出了问题
    102. System.out.println("JWT validation succeeded! " + jwtClaims);
    103. } catch (InvalidJwtException e) {
    104. System.out.println("Invalid JWT! " + e);
    105. // 对JWT无效的(某些)特定原因的编程访问也是可能的
    106. // 在某些情况下,您是否需要不同的错误处理行为。
    107. // JWT是否已经过期是无效的一个常见原因
    108. if (e.hasExpired()) {
    109. System.out.println("JWT expired at " + e.getJwtContext().getJwtClaims().getExpirationTime());
    110. }
    111. // 或者观众是无效的
    112. if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID)) {
    113. System.out.println("JWT had wrong audience: " + e.getJwtContext().getJwtClaims().getAudience());
    114. }
    115. }
    116. }
    117. }

    状态码枚举类

    1. package jkw.vo;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Getter;
    4. /**
    5. * 状态码枚举类
    6. */
    7. @Getter
    8. @AllArgsConstructor
    9. public enum CodeEnum {
    10. SUCCESS(200, "OK"),
    11. SYSTEM_ERROR(500, "系统异常"),
    12. ;
    13. private final Integer code;
    14. private final String message;
    15. }

    返回结果封装类

    1. package jkw.vo;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. import java.io.Serializable;
    5. /**
    6. * 返回结果封装类
    7. */
    8. @Data
    9. @AllArgsConstructor
    10. public class BaseResult<T> implements Serializable {
    11. private Integer code;//状态码(成功:200,失败:其他)
    12. private String message;//提示信息
    13. private T data;//返回数据
    14. //构建成功结果
    15. public static <T> BaseResult<T> ok() {
    16. return new BaseResult(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage(), null);
    17. }
    18. //构建带有数据的成功结果
    19. public static <T> BaseResult<T> ok(T data) {
    20. return new BaseResult(CodeEnum.SUCCESS.getCode(), CodeEnum.SUCCESS.getMessage(), data);
    21. }
    22. }

    用户服务

    1. package jkw.service;
    2. import com.alibaba.nacos.common.utils.StringUtils;
    3. import jkw.utils.JWTUtil;
    4. import jkw.vo.BaseResult;
    5. import org.jose4j.lang.JoseException;
    6. import org.springframework.stereotype.Service;
    7. /**
    8. * 用户服务
    9. */
    10. @Service
    11. public class UserService {
    12. /**
    13. * 登录
    14. *
    15. * @param username
    16. * @param password
    17. * @return
    18. * @throws JoseException
    19. */
    20. public BaseResult login(String username, String password) throws JoseException {
    21. // 1.用户名或者密码校验
    22. if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
    23. return new BaseResult(301, "用户名或者密码为空", null);
    24. }
    25. // 2.判断用户名和密码是否正确
    26. if (username.equals("admin") && password.equals("123456")) {
    27. // 颁发登录token
    28. String token = JWTUtil.sign(1001L, "admin");
    29. return BaseResult.ok(token);
    30. } else {
    31. return new BaseResult(301, "用户名或者密码不对", null);
    32. }
    33. }
    34. }

    用户控制器

    1. package jkw.controller;
    2. import jkw.service.UserService;
    3. import jkw.vo.BaseResult;
    4. import org.jose4j.jwt.MalformedClaimException;
    5. import org.jose4j.lang.JoseException;
    6. import org.springframework.beans.factory.annotation.Autowired;
    7. import org.springframework.web.bind.annotation.PostMapping;
    8. import org.springframework.web.bind.annotation.RequestMapping;
    9. import org.springframework.web.bind.annotation.RestController;
    10. /**
    11. * 用户控制器
    12. */
    13. @RequestMapping("/user")
    14. @RestController
    15. public class UserCon {
    16. @Autowired
    17. private UserService userService;
    18. @PostMapping("/login")
    19. public BaseResult login(String username, String password) throws MalformedClaimException, JoseException {
    20. return userService.login(username, password);
    21. }
    22. }

    higress配置

    文档

    https://higress.io/zh-cn/docs/plugins/jwt-auth/

    1.路由配置【8007-higress-jwt 精确匹配 | /user/login test-higress-jwt-8007.DEFAULT-GROUP.public.nacos

    2.插件配置【全局,配置】:策略:JWT Auth 

    1. consumers:
    2. - issuer: "user"
    3. jwks: |
    4. {
    5. "keys": [
    6. {
    7. "kty":"RSA",
    8. "n":"ziX1yaqbQWGGto1B4NxvmYifUTSigM2LEN0KubXoxt7t9Nz9NaqES4Y36e_v_DhT_v0mKC74pReTWcDVSXZE49jFWphBNlcsnWOsjMlntVlZ_rOQyLZEMhcqshQVvBU8UPFoc77UYBddAjnnShdrSsP5e9qMeMAJVsRCEJZ3Y1IkwRmUGThhmqXNGn1UEhtMSrXDewkre7AWNVkixky7SV-0WhdA6QrEPtLfXoXBQseO2QgRAA73Gc7rs1hF89lKphcBx_mtngonAltNtGGuDhXriBCnt_zuUx8Bt7S-XlECxjSFtHbWKsgOuWTXxMIOVMHoerinsDP1AKmIqPo5xw",
    9. "e":"AQAB",
    10. "kid": "keyId",
    11. }
    12. ]
    13. }
    14. name: "consumer1"
    15. global_auth: false

    3.路由配置【路由级别,使用】:策略:JWT Auth

    1. allow:
    2. - "consumer1"

    4.测试步骤:开启服务test-higress8006和test-higress-jwt-8007

    首先访问http://www.jkw.com/user/login【admin/123456】获取jwt,

    然后在访问配置jwt Auth的http://www.jkw.com/test/index

    【请求头中添加Authorization,值为Bearer jwt的值,前面一定要加Bearer 】

  • 相关阅读:
    剑指 Offer 14- II. 剪绳子 II
    070:mapboxGL加载含有shp文件的zip,显示图形
    基于K8s构建Jenkins持续集成平台(部署流程)(转)
    SpringMvc源码分析-请求流程(一)
    【高性能计算是如何变现的?】
    网络原理
    Go 学习笔记(89) — 接口类型变量的等值比较操作(nil 接口变量、空接口类型变量、非空接口类型变量)
    k3s 上的 kube-ovn 轻度体验
    centos通过docker安装rabbitMq和延迟队列说明
    Java的<? super T>和<? extends R>理解与应用
  • 原文地址:https://blog.csdn.net/m0_63040701/article/details/138579818