在 Spring 安全中模拟 JwtDecoder

Mock JwtDecoder in Spring Security

这是我的服务 class 方法中的代码,用于根据传递的身份验证令牌获取 JWT 令牌。

        NimbusJwtDecoder decoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(userTokenUrl);
        Jwt jwt = decoder.decode(authResponse.authenticationResult().idToken());
        Map<String, Object> claims = jwt.getClaims();
        if(!ACTIVE.equals(claims.get(CUSTOM_STATUS).toString())) {
            throw new IllegalArgumentException("User is not active");
        }

我想为这个服务class方法写一个JUnit。我尝试了以下方法,但在尝试解码令牌 ID 时出错 IllegalArgumentException:尝试解码 Jwt 时发生错误:已签名的 JWT 被拒绝:需要另一种算法,或者找不到匹配的密钥

    NimbusJwtDecoder decoder = mock(NimbusJwtDecoder.class);
    when(decoder.decode(ArgumentMatchers.anyString()))
            .thenReturn(Jwt.withTokenValue(getToken()).header("typ", "JWT").header("alg", "HS256").claim("custom:status", "active").build());

我不确定这是可行的解决方案,但这对我有用。我通过提取我的 jwt 解码器代码来重构我的代码。我创建了一个返回 Jwt 对象的新方法。

public Jwt getJwt(InitiateAuthResponse authResponse) {
    NimbusJwtDecoder decoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(userTokenUrl);
    return decoder.decode(authResponse.authenticationResult().idToken());
}

我在测试中模拟这个方法class。

    Map<String, Object> headers = new HashMap<>();
    headers.put(HttpHeaders.AUTHORIZATION, "Bearer token");
    headers.put("typ", "JWT");
    headers.put("alg", "none");

    Map<String, Object> claims = new HashMap<>();
    claims.put("custom:status", "active");
    
    Jwt jwt = new Jwt("fake-token", Instant.now(), Instant.now().plusSeconds(100), headers, claims);
    doReturn(jwt).when(spyService).getJwt(ArgumentMatchers.any());