简体   繁体   English

我的 spring 启动没有使用 Keycloak 验证 JWT 令牌?

[英]My spring boot does not validate JWT token with the Keycloak?

I have a Spring Boot + Keycloak project and I found out that the Spring Boot does not validate the JWT with the keycloak.我有一个 Spring Boot + Keycloak 项目,我发现 Spring Boot 没有使用 keycloak 验证 JWT。 For example if I get a token from Keycloak and turn off the Keycloak, I still can use this JWT token to access my end points.例如,如果我从 Keycloak 获得令牌并关闭 Keycloak,我仍然可以使用此 JWT 令牌访问我的端点。 I have this security configurer class:我有这个安全配置器 class:

@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);
    }

}

The "converter" is nothing special, just extracts the roles out of JWT token and returns a list of them. “转换器”没有什么特别之处,只是从 JWT 令牌中提取角色并返回它们的列表。

How to force the Spring Security to validate the JWT token?如何强制 Spring 安全验证 JWT 令牌?

application.yml:应用程序.yml:

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

You can look at the implementation of JwtDecoders.fromOidcIssuerLocation(issuerUri) .您可以查看JwtDecoders.fromOidcIssuerLocation(issuerUri)的实现。

What is happening is that the keys are being fetched at the startup of your application and the application caches them in order to perform the validation after.正在发生的事情是在您的应用程序启动时获取密钥,并且应用程序缓存它们以便在之后执行验证。 With this in mind, even if you turn off Keycloak the JWT will still be validated because the keys are still cached.考虑到这一点,即使您关闭 Keycloak,JWT 仍将被验证,因为密钥仍被缓存。

The JWT tokens are been cached in your springboot application, this is the default cache store. JWT 令牌已缓存在您的 springboot 应用程序中,这是默认的缓存存储。 In order to delete this token from your springboot app use should use some custom caches like redis cache to be configured in your app instead of default.为了从您的 springboot 应用程序中删除此令牌,应使用一些自定义缓存,例如 redis 缓存,以在您的应用程序中配置而不是默认缓存。 There is no possible way to delete the tokens stored in default caches.无法删除存储在默认缓存中的令牌。 The token will automatically get invalidate only after the timeout that's been set inside token只有在令牌内部设置的超时后,令牌才会自动失效

JWTs are meant to be validated offline, and it is what usually happens. JWT 旨在离线验证,并且通常会发生这种情况。 The receiving application (consumer of JWT), does not need constant access to the Authorization Server in order to be able to validate a JWT.接收应用程序(JWT 的消费者)不需要持续访问授权服务器即可验证 JWT。 Even though Spring can't talk to your Keycloak, it does not mean that tokens are not validated.即使 Spring 无法与您的 Keycloak 通信,但这并不意味着令牌未经过验证。 As others pointed out, Spring caches the keys used to validate JWTs' signature and will use the cache if it can.正如其他人指出的那样,Spring 缓存了用于验证 JWT 签名的密钥,如果可以的话,将使用缓存。

If, for some reason, you want your service / API to validate the JWT online (maybe because you want to implement a mechanism to revoke tokens), you could switch to using opaque tokens with Token Introspection .如果出于某种原因,您希望您的服务 / API 在线验证 JWT (可能是因为您想实现一种机制来撤销令牌),您可以切换到使用带有Token Introspection的不透明令牌。 On every request your service will have to call Keycloak to exchange the opaque token for a JWT.对于每个请求,您的服务都必须调用 Keycloak 以将不透明令牌交换为 JWT。 Mind that this solution will use much more resources, and you should use it only if you have strong reasons for it.请注意,此解决方案将使用更多资源,并且只有在您有充分理由的情况下才应使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM