Spring Boot微服务JWT认证配置匹配仍报"Another algorithm expected, or no matching key(s) found"错误排查求助
我正在搭建一套Spring Boot微服务架构,其中auth-service负责生成JWT令牌,user-service负责校验令牌。但现在遇到了一个棘手的问题:用auth-service生成的有效令牌请求user-service时,始终返回401 Unauthorized错误。
具体错误日志
user-service的日志输出如下:
An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found
这让我很困惑,因为我已经仔细配置了两个服务,确保它们都使用HS512算法和完全相同的密钥。
我的配置详情
1. auth-service - 令牌生成代码(JwtService.java)
这个服务使用io.jsonwebtoken(jjwt)库创建令牌,并指定用SignatureAlgorithm.HS512签名:
package com.grambasket.authservice.security; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.nio.charset.StandardCharsets; import java.security.Key; import java.util.Date; import java.util.Map; @Service @Slf4j public class JwtService { @Value("${spring.security.oauth2.resourceserver.jwt.secret-key}") private String jwtSecret; private Key signInKey; @PostConstruct public void init() { this.signInKey = Keys.hmacShaKeyFor(jwtSecret.getBytes(StandardCharsets.UTF_8)); log.info("JWT signing key initialized for use with HS512 algorithm."); } private String buildToken(Map<String, Object> extraClaims, UserDetails userDetails, long expiration) { // ... 其他声明逻辑(subject、issuer等) return Jwts.builder() // ... 其他配置 .signWith(signInKey, SignatureAlgorithm.HS512) // 显式指定HS512 .compact(); } // ... 类的其他方法 }
2. user-service - 令牌校验配置(SecurityConfig.java)
这个服务作为OAuth2资源服务器,使用NimbusJwtDecoder校验令牌,同样指定了HmacSHA512算法:
package com.grambasket.userservice.security; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; @Configuration @EnableWebSecurity @Slf4j public class SecurityConfig { @Value("${spring.security.oauth2.resourceserver.jwt.secret-key}") private String jwtSecret; // ... 其他Bean和配置 @Bean public JwtDecoder jwtDecoder() { // 指定使用HmacSHA512 SecretKeySpec secretKey = new SecretKeySpec(jwtSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA512"); log.info("Configuring JwtDecoder with HmacSHA512 algorithm."); return NimbusJwtDecoder.withSecretKey(secretKey).build(); } }
3. 共享的配置文件(application.yml)
两个服务使用完全相同的密钥,我试过简单密钥和长的Base64编码密钥(满足HS512的长度要求),但错误依旧:
- auth-service/application.yml
security: oauth2: resourceserver: jwt: secret-key: "mysupersecretkeymysupersecretkey12"
- user-service/application.yml
spring: security: oauth2: resourceserver: jwt: secret-key: "mysupersecretkeymysupersecretkey12"
我已经尝试过的解决方案
- 算法一致性检查:反复确认签名(
SignatureAlgorithm.HS512)和解码("HmacSHA512")的配置完全匹配 - 密钥一致性验证:两个服务的密钥完全相同,我是直接复制粘贴的,确保没有拼写错误
- 密钥长度调整:把初始的短密钥替换成了超过64字节的长密钥,满足HS512的长度要求,但错误仍然存在
- 清理构建缓存:执行了
mvn clean install -U,还手动删除了.m2仓库的缓存文件,排除缓存问题 - 公共端点测试:在user-service里创建了一个公共的
/ping端点,访问完全正常,只有当请求头里带有Authorization: Bearer <token>时才会返回401,说明问题确实出在JWT校验环节
明明算法和密钥都完全匹配,为什么JwtAuthenticationProvider还是会抛出Another algorithm expected, or no matching key(s) found这个错误?会不会是签名用的io.jsonwebtoken库和Spring解码用的com.nimbusds库之间存在隐性冲突?或者pom.xml里的非GA版本依赖导致了这种不可预测的问题?真心求各位大佬指点迷津!
内容来源于stack exchange

