使用刷新令牌时 Spring Boot JWT 令牌无效签名
Posted
技术标签:
【中文标题】使用刷新令牌时 Spring Boot JWT 令牌无效签名【英文标题】:Spring Boot JWT tokens invalid signature when using refrest token 【发布时间】:2020-02-12 07:35:23 【问题描述】:所以我正在构建一个 OAuth 服务器。
我可以正常访问我的授权服务器,但是签名似乎无效。
将其输入https://jwt.io/ 会产生无效签名。更糟糕的是,当我尝试使用刷新令牌时,我得到 InvalidTokenException,无法将访问令牌转换为 JSON。
这个秘密来自JwtAccessTokenConverter.java
protected Map<String, Object> decode(String token)
try
Jwt jwt = JwtHelper.decodeAndVerify(token, verifier);
String claimsStr = jwt.getClaims();
Map<String, Object> claims = objectMapper.parseMap(claimsStr);
if (claims.containsKey(EXP) && claims.get(EXP) instanceof Integer)
Integer intValue = (Integer) claims.get(EXP);
claims.put(EXP, new Long(intValue));
this.getJwtClaimsSetVerifier().verify(claims);
return claims;
catch (Exception e)
throw new InvalidTokenException("Cannot convert access token to JSON", e);
真正的例外是计算的签名与给定的签名不匹配。因此,由于某种原因,签名实际上并未签署所有内容。我有一个自定义令牌增强器,它放置了几个额外的值。我怀疑这没有得到签名,我不知道为什么。
下面是我的授权服务器
@Configuration
@EnableAuthorizationServer
@EnableConfigurationProperties(SecurityProperties::class)
class AuthorizationServerConfiguration(private val dataSource: DataSource, private val passwordEncoder: PasswordEncoder,
private val authenticationManager: AuthenticationManager, private val securityProperties: SecurityProperties,
private val userDetailsService: UserDetailsService) : AuthorizationServerConfigurerAdapter()
private var jwtAccessTokenConverter: JwtAccessTokenConverter? = null
private var tokenStore: TokenStore? = null
@Bean
fun tokenEnhancer(): CustomTokenEnhancer
return CustomTokenEnhancer()
@Bean
fun loggingExceptionTranslator(): DefaultWebResponseExceptionTranslator
return object : DefaultWebResponseExceptionTranslator()
@Throws(Exception::class)
override fun translate(e: Exception): ResponseEntity<OAuth2Exception>
// This is the line that prints the stack trace to the log. You can customise this to format the trace etc if you like
e.printStackTrace()
// Carry on handling the exception
val responseEntity = super.translate(e)
val headers = HttpHeaders()
headers.setAll(responseEntity.headers.toSingleValueMap())
val excBody = responseEntity.body
return ResponseEntity(excBody, headers, responseEntity.statusCode)
@Bean
fun tokenStore(): TokenStore
if (tokenStore == null)
tokenStore = JwtTokenStore(tokenEnhancer())
return tokenStore as TokenStore
@Bean
fun tokenServices(tokenStore: TokenStore,
clientDetailsService: ClientDetailsService): DefaultTokenServices
val tokenServices = DefaultTokenServices()
tokenServices.setSupportRefreshToken(true)
tokenServices.setTokenStore(tokenStore)
tokenServices.setAuthenticationManager(this.authenticationManager)
tokenServices.setAccessTokenValiditySeconds(securityProperties.tokenTimeToLive)
return tokenServices
@Bean
fun jwtAccessTokenConverter(): JwtAccessTokenConverter
if (jwtAccessTokenConverter != null)
return jwtAccessTokenConverter as JwtAccessTokenConverter
val jwtProperties = securityProperties.jwt
val keyPair = jwtProperties?.let keyStoreKeyFactory(it) ?.let keyPair(jwtProperties, it)
jwtAccessTokenConverter = CustomTokenEnhancer()
jwtAccessTokenConverter!!.setKeyPair(keyPair!!)
jwtAccessTokenConverter!!.afterPropertiesSet()
return jwtAccessTokenConverter as JwtAccessTokenConverter
@Throws(Exception::class)
override fun configure(clients: ClientDetailsServiceConfigurer)
clients.jdbc(this.dataSource)
override fun configure(endpoints: AuthorizationServerEndpointsConfigurer)
endpoints.authenticationManager(this.authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter())
.userDetailsService(this.userDetailsService)
.tokenStore(tokenStore())
override fun configure(oauthServer: AuthorizationServerSecurityConfigurer)
oauthServer.passwordEncoder(this.passwordEncoder).tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
private fun keyPair(jwtProperties: SecurityProperties.JwtProperties?, keyStoreKeyFactory: KeyStoreKeyFactory): KeyPair
return keyStoreKeyFactory.getKeyPair(jwtProperties?.keyPairAlias, jwtProperties?.keyPairPassword?.toCharArray())
private fun keyStoreKeyFactory(jwtProperties: SecurityProperties.JwtProperties): KeyStoreKeyFactory
return KeyStoreKeyFactory(jwtProperties.keyStore, jwtProperties.keyStorePassword?.toCharArray())
【问题讨论】:
【参考方案1】:我需要在以下行中使用 bean
@Bean
fun tokenStore(): TokenStore
return JwtTokenStore(jwtAccessTokenConverter())
【讨论】:
以上是关于使用刷新令牌时 Spring Boot JWT 令牌无效签名的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot JWT - 如何实现刷新令牌和注销 REST-API
Spring Boot 安全性 - 允许使用过期 JWT 令牌的用户请求