在 Spring boot JWT Plus Oauth2, TokenStore findTokensByClientId(clientId) returns 空白数组(我想要活动令牌)

In Spring boot JWT Plus Oauth2, TokenStore findTokensByClientId(clientId) returns blank array (I want active tokens)

我用 jwt 和 oauth2(在内存中)实现了 spring 引导。

此处令牌位于内存中而不是数据库中。

但是当我使用 tokenStore.findTokensByClientId(clientId) 时,它 returns 在下面的情况下是空白数组

例子

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {


    static final String CLIEN_ID = "vishvas-client";
    static final String CLIENT_SECRET = "a$kfH4W.jyBuqvX5TLu.OfbOEUtScm4V9FEUDvGI8AWPaqObUOQ7HJ2"; // vishvas-secret
    static final String GRANT_TYPE_PASSWORD = "password";
    static final String AUTHORIZATION_CODE = "authorization_code";
    static final String REFRESH_TOKEN = "refresh_token";
    static final String IMPLICIT = "implicit";
    static final String SCOPE_READ = "read";
    static final String SCOPE_WRITE = "write";
    static final String TRUST = "trust";
    static final int ACCESS_TOKEN_VALIDITY_SECONDS = 12 * 60 * 60; // 12 hour
    static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 24 * 60 * 60; // 24 hour

    @Autowired
    private AuthenticationManager authenticationManager;

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("as466gf");
        return converter;
    }

    @Bean
    public TokenStore tokenStore() {
        //  return new InMemoryTokenStore();   // Success : working but same access token generated every time. i want different access tokens
        return new JwtTokenStore(accessTokenConverter()); // Error :  tokenStore.findTokensByClientId(clientId) returns blank

    }

    @Override
    public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {

        configurer.inMemory().withClient(CLIEN_ID).secret(CLIENT_SECRET)
                .authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT)
                .scopes(SCOPE_READ, SCOPE_WRITE, TRUST).accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
                .refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager)
                .accessTokenConverter(accessTokenConverter());
    }
}


@RestController
@RequestMapping("/api/tokens")
public class TokensEndpointController {

    @Autowired
    private TokenStore tokenStore;

    @CrossOrigin
    @SuppressWarnings({ "unchecked", "rawtypes", "deprecation" })
    @GetMapping
    public ResponseEntity<?> findAllActiveSessions(@RequestParam String clientId,
            HttpServletRequest httpServletRequest) {

        try {

            String username = httpServletRequest.getUserPrincipal().getName();

            Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByClientId(clientId);
            List<String> tokenValues = tokens.stream().map(OAuth2AccessToken::getValue).collect(Collectors.toList());

            System.out.println("tokenValues : " + tokenValues); // Blank array

            return ResponseEntity.ok(new ResponseWrapperDTO(HttpServletResponse.SC_OK,
                    httpServletRequest.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString(),
                    "Tokens got successfully.", tokenValues));

        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity(
                    new ResponseErrorDTO(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                            MethodUtils.getApiPathFromHttpServletRequest(httpServletRequest), e.getMessage()),
                    HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

}

示例说明:

  1. tokenStore()方法中,如果我使用return new InMemoryTokenStore();那么我可以使用api(http://localhost:8080/api/tokens?clientId=vishvas-client)成功获取所有令牌,但每次生成相同的访问令牌

  2. tokenStore() 方法中,如果我使用 return new JwtTokenStore(accessTokenConverter()); 那么 api (http://localhost:8080/api/tokens?clientId=vishvas-client) returns 空白数组。 (第2点有问题,拿不到代币)

  1. 在第一个配置中“InMemoryTokenStore”:
    • 标准的oauth2令牌生成方法,意味着将为每个用户生成一个令牌 并且它将被 stored (所以当你向授权服务器请求客户端的令牌时,它会获取它而不生成),直到令牌 expire 然后将生成另一个令牌

That's why you are getting the same token every time, but when this token will expire the authorize server will generate another one

  1. 在第二个配置中“JwtTokenStore”:
    • 是标准的 oauth2 jwt 令牌生成方法,意味着每次您请求令牌时,授权服务器都会为您生成一个令牌并且 doesn' t 存储 它在内存中
    • 此时如果您使用的是 JWT 令牌,服务器需要是无状态的,这意味着没有令牌存储或用户信息存储,因为 JWT 令牌是 自包含的 不需要存储令牌或用户信息的服务器

That's why you are getting different token every time, but an empty list

你可以检查 JwtTokenStore class 在这个 link at Line 162, 你会发现默认是给出一个空列表

因此对于标准配置,您应该使用 JwtTokenStore