Micronaut 配置未发出 JWT 刷新令牌

Posted

技术标签:

【中文标题】Micronaut 配置未发出 JWT 刷新令牌【英文标题】:Micronaut config not issuing a JWT refresh token 【发布时间】:2021-09-17 17:51:33 【问题描述】:

我的application.yml 中有以下配置。根据规范,除了JWT 响应中的访问令牌之外,这应该发出一个刷新令牌,但我只得到访问令牌而不是刷新令牌。

我错过了什么吗?

token:
  jwt:
    signatures:
      secret:
        generator:
          refresh-token:
            secret: "$JWT_GENERATOR_SIGNATURE_SECRET:pleaseChangeThisSecretForANewOne"  
          secret: "$JWT_GENERATOR_SIGNATURE_SECRET:pleaseChangeThisSecretForANewOne"     

【问题讨论】:

可能是您对某些 micronaut 参数的 yaml 路径错误...这是来自我的 jwt 产品设置,但采用 *.properties 格式 micronaut.security.authentication=bearer micronaut.security.token.jwt.signatures.secret.generator.secret="$JWT_GENERATOR_SIGNATURE_SECRET\:unit_testing_jwt_generator_secret" micronaut.security.token.jwt.generator.refresh-token.secret="$JWT_GENERATOR_REFRESH_SECRET\:unit_testing_jwt_refresh_secret" 并且刷新令牌至少应出现在登录端点上(并从变量 micronaut.security.endpoints.oauth.path 刷新端点路径)。 【参考方案1】:

我在 Micronaut v3.1.4 中发现了这个问题。它需要一个实现 RefreshTokenPersistence 的类。这对我有用。

import io.micronaut.security.authentication.Authentication;
import io.micronaut.security.token.event.RefreshTokenGeneratedEvent;
import io.micronaut.security.token.refresh.RefreshTokenPersistence;
import jakarta.inject.Singleton;
import org.reactivestreams.Publisher;

@Singleton
public class CustomRefreshTokenPersistence implements RefreshTokenPersistence 

    @Override
    public void persistToken(final RefreshTokenGeneratedEvent event) 
   
    

    @Override
    public Publisher<Authentication> getAuthentication(final String refreshToken) 
        return null;
    

【讨论】:

【参考方案2】:

您可能缺少RefreshTokenPersistence 的实现。

我建议您阅读这部分 micronaut 的安全文档:https://micronaut-projects.github.io/micronaut-security/latest/guide/#refresh

这是持久性单元的一个非常简单的实现。请不要忘记将@Singleton 添加到您的实施中。我完全错过了这一点,这就是为什么 micronaut 最初没有在我自己的项目中生成刷新令牌的原因。

import io.micronaut.security.authentication.UserDetails;
import io.micronaut.security.token.event.RefreshTokenGeneratedEvent;
import io.micronaut.security.token.refresh.RefreshTokenPersistence;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import org.reactivestreams.Publisher;

import javax.inject.Singleton;
import java.util.HashMap;
import java.util.Map;

@Singleton
public class MyRefreshTokenPersistence implements RefreshTokenPersistence 

    private final Map<String, UserDetails> storage = new HashMap<>();

    @Override
    public void persistToken(RefreshTokenGeneratedEvent event) 
        storage.put(event.getRefreshToken(), event.getUserDetails());
    

    @Override
    public Publisher<UserDetails> getUserDetails(String refreshToken) 
        return Flowable.create(emitter -> 
            final UserDetails userDetails = storage.get(refreshToken);
            if ( userDetails != null ) 
                emitter.onNext(userDetails);
                emitter.onComplete();
             else 
                emitter.onError(new IllegalArgumentException("refresh token unknown"));
            
        , BackpressureStrategy.BUFFER);
    

【讨论】:

发布和持久刷新令牌是完全不同的过程。 @Leandro Lima 不,你错了。假设认证方式为“承载”。见:AccessRefreshTokenLoginHandler line 54 call to generate &gt; DefaultAccessRefreshTokenGenerator line 95 call to generateRefreshToken &gt; same class line 107if (beanContext.containsBean(RefreshTokenPersistence.class)) ...。将检查 RefreshTokenPersistence 的存在。

以上是关于Micronaut 配置未发出 JWT 刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章

使用过期令牌发出同时 API 请求时如何避免多个令牌刷新请求

当 jwt 刷新令牌未过期时,React Native 应用程序注销

Firebase php-jwt 令牌刷新

黑名单/验证/生成 JWT 刷新令牌

刷新后如何使以前的 JWT 令牌无效

DJANGO-GRAPHQL-JWT:我们如何知道刷新令牌发布后的年龄?