关于SpringBoot2.x集成SpringSecurity+JJWT(0.7.0-->0.11.5)生成Token登录鉴权的问题

项目场景:

问题:遵循版本稳定的前提下,搭建权限认证框架,基于SpringBoot2.x+SpringSecurity向上依赖+jjwt0.7.0构建用户认证鉴权,起因是某L觉得jjwt0.7.0版本,官方已经放弃维护,且从maven仓库对0.7.0版本使用量对比来看,遂放弃0.7.0转而升级为0.11.5,由此引发的token生成和解析的一系列BUG
pom.xml


<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0modelVersion>
	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.7.14version>
		<relativePath/> 
	parent>
	<groupId>cn.isungent.irdgroupId>
	<artifactId>epdxartifactId>
	<version>0.0.1-SNAPSHOTversion>
	<name>epdxname>
	<description>Enterprise Data Platformdescription>
	<properties>
		<java.version>1.8java.version>
		<mybatis-plus.version>3.5.3.2mybatis-plus.version>
	properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
			
		dependency>
		<dependency>
			<groupId>org.mybatis.spring.bootgroupId>
			<artifactId>mybatis-spring-boot-starterartifactId>
			<version>2.3.1version>
		dependency>
		<dependency>
			<groupId>com.h2databasegroupId>
			<artifactId>h2artifactId>
			<scope>runtimescope>
		dependency>
		<dependency>
			<groupId>com.mysqlgroupId>
			<artifactId>mysql-connector-jartifactId>
			<scope>runtimescope>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-devtoolsartifactId>
			<scope>runtimescope>
			<optional>trueoptional>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-configuration-processorartifactId>
			<optional>trueoptional>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-testartifactId>
			<scope>testscope>
		dependency>






		
		<dependency>
			<groupId>com.baomidougroupId>
			<artifactId>mybatis-plus-boot-starter-testartifactId>
			<version>${mybatis-plus.version}version>
			<scope>testscope>
		dependency>

		
		<dependency>
			<groupId>com.google.code.gsongroupId>
			<artifactId>gsonartifactId>
			<version>2.10.1version>
		dependency>
		
		<dependency>
			<groupId>org.apache.commonsgroupId>
			<artifactId>commons-lang3artifactId>
			<version>3.12.0version>
		dependency>
		
		<dependency>
			<groupId>org.mockitogroupId>
			<artifactId>mockito-coreartifactId>
			<version>4.11.0version>
			<scope>testscope>
		dependency>
		
		<dependency>
			<groupId>io.springfoxgroupId>
			<artifactId>springfox-swagger2artifactId>
			<version>3.0.0version>
		dependency>
		<dependency>
			<groupId>io.springfoxgroupId>
			<artifactId>springfox-boot-starterartifactId>
			<version>3.0.0version>
		dependency>
		<dependency>
			<groupId>io.springfoxgroupId>
			<artifactId>springfox-swagger-uiartifactId>
			<version>3.0.0version>
		dependency>

		<dependency>
			<groupId>com.baomidougroupId>
			<artifactId>mybatis-plus-boot-starterartifactId>
			<version>${mybatis-plus.version}version>
		dependency>

		<dependency>
			<groupId>com.baomidougroupId>
			<artifactId>mybatis-plus-extensionartifactId>
			<version>${mybatis-plus.version}version>
		dependency>

		<dependency>
			<groupId>org.mariadb.jdbcgroupId>
			<artifactId>mariadb-java-clientartifactId>
			<scope>runtimescope>
			<version>2.7.10version>
		dependency>

		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-securityartifactId>
		dependency>

		<dependency>
			<groupId>io.jsonwebtokengroupId>
			<artifactId>jjwt-apiartifactId>
			<version>0.11.5version>
		dependency>
		<dependency>
			<groupId>io.jsonwebtokengroupId>
			<artifactId>jjwt-implartifactId>
			<version>0.11.5version>
			<scope>runtimescope>
		dependency>
		<dependency>
			<groupId>io.jsonwebtokengroupId>
			<artifactId>jjwt-jacksonartifactId> 
			<version>0.11.5version>
			<scope>runtimescope>
		dependency>

	dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.bootgroupId>
				<artifactId>spring-boot-maven-pluginartifactId>
			plugin>
		plugins>
	build>

project>

yml配置

spring:
  datasource:
    driverClassName: org.h2.Driver
    url: jdbc:h2:mem:test-db
  sql:
    init:
      data-locations: classpath:db/data.sql
      encoding: utf8
      schema-locations: classpath:db/schema.sql

  h2:
    console:
      enabled: true
      path: /h2-console


jwt:
  secret: kiki
  expiration: 18000
  tokenHeader: Authorization
  loginFailMaxNum: 5
  tokenPrefix: authorization-
  authUserName: AuthorizationUserName
  authRole: admin
  authEmail: [email protected]

JwtTokenUtil

package cn.isungent.ird.epdx.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author kiki
 * @date 2023/10/10
 * @description
 */
@Component
@ConfigurationProperties(prefix = "jwt")
public class JwtTokenUtil {

    private static final String CLAIM_KEY_USERNAME = "sub";
    private static final String CLAIM_KEY_CREATED = "$2a$10$khMzocJpIzuhkiqSFLQ/euwedqw/ocRjZUI0SsS/TDY0e4RZIxh0C";

    private String secret;

    private Integer expiration;

    public Claims getClaimsFromToken(String token, String secret) {
        Claims claims = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
        return claims;
    }

    private String generateToken(Map<String, Object> claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    public String generateToken(String userEmail) {
        Map<String, Object> claims = new HashMap<>(16);
        claims.put(CLAIM_KEY_USERNAME, userEmail);
        claims.put(CLAIM_KEY_CREATED, new Date());
        return generateToken(claims);
    }

    private Date generateExpirationDate() {
        return new Date(System.currentTimeMillis() + expiration * 1000);
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public Integer getExpiration() {
        return expiration;
    }

    public void setExpiration(Integer expiration) {
        this.expiration = expiration;
    }
}

如下,升级版本后,postman模拟登录报错


关于SpringBoot2.x集成SpringSecurity+JJWT(0.7.0-->0.11.5)生成Token登录鉴权的问题_第1张图片
consul打印

io.jsonwebtoken.security.WeakKeyException: The signing key's size is 24 bits which is not secure enough for the HS512 algorithm.  The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HS512 MUST have a size >= 512 bits (the key size must be greater than or equal to the hash output size).  Consider using the io.jsonwebtoken.security.Keys class's 'secretKeyFor(SignatureAlgorithm.HS512)' method to create a key guaranteed to be secure enough for HS512.  See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.
	at io.jsonwebtoken.SignatureAlgorithm.assertValid(SignatureAlgorithm.java:387)

问题描述

翻译:The signing key's size is 24 bits which is not secure enough for the HS512 algorithm. The JWT JWA Specification (RFC 7518, Section 3.2) states that keys used with HS512 MUST have a size >= 512 bits (the key size must be greater than or equal to the hash output size). Consider using the io.jsonwebtoken.security.Keys class's 'secretKeyFor(SignatureAlgorithm.HS512)' method to create a key guaranteed to be secure enough for HS512. See https://tools.ietf.org/html/rfc7518#section-3.2 for more information.大概意思是说:io.jsonwebtoken.security.WeakKeyException:签名密钥的大小是24位,对于HS512算法来说不够安全。JWT JWA规范(RFC 7518, Section 3.2)规定,与HS512一起使用的密钥的大小必须大于= 512位(密钥大小必须大于或等于哈希输出的大小)。考虑使用io.jsonwebtoken.security.Keys类的'secretKeyFor(signaturealalgorithm .HS512)'方法来创建一个保证对HS512足够安全的密钥。参见https:tools.ietf.orghtmlrfc7518section-3.2获取更多信息

综上:就是说升级后,那个密钥的长度要大于512,就是yml中配置secrect的配置项,太短了


解决方案:

提示:修改yml配置项jwt.secrect的密钥字符串的值为AAAAB3NzaC1yc2EAAAADAQABAAABgQDb73eBHCS6avoS2hnC3Zzf3N1JQax2Wg2Z9uvxIq6MlORGGFnrhV3jlDD2+iXsoM1UUEOIvhGMeeAt9EWJ8MVIbKOfHzChwkHojUlTFd87qWxCEfS9LWcl1d1Hsx9R1R5Uj31xfP76XlQAR+vhOGQtk1RW1RInxWZVo/++Bts9iNCvxMCx5c/v9Dhgrkj+CD2b1YoYILn6xZjjRMOVB33+xV5ERO5mluHQV+8xKght75WQqaOz4lARBsfxgOpMAzVU6IYCz2qGztrYNCjnjgBLee+Kok4belJM7fjW5ntuP7kPGLAnxfkZQWdR/iG71PuZmcNngesxaqIxVD3Hwa6Qfv2cUsS2bJn/L51uT5k07obZF5poxssCx7qzhe+1Aa1sDfct2vfkqzYCikI9ioKqM999dKiqYPP13ThfYfaWRuVKor3/tgZkbKmhf7+BH8pLnS03/ewZZgwxxx=

注意:值可以是任意字符串,非固定。

你可能感兴趣的:(spring,boot,SpringSecurity,jwt,bug,json)