【问题标题】:My spring boot does not validate JWT token with the Keycloak?我的 Spring Boot 不使用 Keycloak 验证 JWT 令牌?
【发布时间】:2021-08-16 19:13:07
【问题描述】:

我有一个 Spring Boot + Keycloak 项目,我发现 Spring Boot 没有使用 keycloak 验证 JWT。例如,如果我从 Keycloak 获得令牌并关闭 Keycloak,我仍然可以使用此 JWT 令牌访问我的端点。我有这个安全配置器类:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
@RequiredArgsConstructor
public class KeycloakSecurityConfigurer extends WebSecurityConfigurerAdapter {

    private final RoleConverter converter;

    @Value("${spring.security.oauth2.keycloak.jwt.issuer-uri}")
    private String issuerUri;

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http.headers().frameOptions().disable()
            .and()
        .csrf().disable()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
        .oauth2ResourceServer(
                oauth2ResourceServer -> oauth2ResourceServer.jwt(
                        jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())));
        
        http.authorizeRequests().antMatchers("/**").authenticated();
    }

    private Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter() {
        JwtAuthenticationConverter jwtConverter = new JwtAuthenticationConverter();
        jwtConverter.setJwtGrantedAuthoritiesConverter(converter);
        return jwtConverter;
    }

    @Bean
    public JwtDecoder jwtDecoder() {
        return JwtDecoders.fromOidcIssuerLocation(issuerUri);
    }

}

“转换器”没什么特别的,只是从 JWT 令牌中提取角色并返回它们的列表。

如何强制 Spring Security 验证 JWT 令牌?

application.yml:

spring:
   security:
      oauth2:
         keycloak:
            jwt:
               issuer-uri: http://localhost:8180/auth/realms/test-realm

【问题讨论】:

  • 你能告诉我们你的application.yml文件吗?
  • 添加到问题

标签: java spring spring-boot spring-security jwt


【解决方案1】:

JWT 旨在离线验证,而且通常会发生这种情况。接收应用程序(JWT 的消费者)不需要持续访问授权服务器即可验证 JWT。尽管 Spring 无法与您的 Keycloak 对话,但这并不意味着令牌未经过验证。正如其他人指出的那样,Spring 缓存了用于验证 JWT 签名的密钥,如果可以的话,将使用缓存。

如果出于某种原因,您希望您的服务/API 在线验证 JWT(可能是因为您想实现一种机制来撤销令牌),您可以切换到使用带有 Token Introspection 的不透明令牌。在每次请求时,您的服务都必须调用 Keycloak 以将不透明令牌交换为 JWT。请注意,此解决方案将使用更多资源,只有在您有充分理由的情况下才应使用它。

【讨论】:

    【解决方案2】:

    JWT 令牌已缓存在您的 springboot 应用程序中,这是默认的缓存存储。为了从您的 springboot 应用程序中删除此令牌,应使用一些自定义缓存,例如在您的应用程序中配置的 redis 缓存,而不是默认缓存。无法删除存储在默认缓存中的令牌。只有在令牌内部设置的超时后,令牌才会自动失效

    【讨论】:

      【解决方案3】:

      你可以看看JwtDecoders.fromOidcIssuerLocation(issuerUri)的实现。

      发生的情况是,在您的应用程序启动时获取密钥,应用程序缓存它们以便在之后执行验证。考虑到这一点,即使您关闭 Keycloak,JWT 仍将被验证,因为密钥仍被缓存。

      【讨论】:

        猜你喜欢
        • 2023-02-25
        • 1970-01-01
        • 2017-09-13
        • 2021-09-04
        • 2020-04-23
        • 1970-01-01
        • 1970-01-01
        • 2021-09-01
        • 1970-01-01
        相关资源
        最近更新 更多