Spring Security + OAuth:本地JWT验证的设置

jmp7cifd  于 2023-10-15  发布在  Spring
关注(0)|答案(2)|浏览(150)

我正在构建由Keycloak保护的微服务应用程序,并希望保护每个微服务。这里已经写了很多次了,每次你想验证你的令牌时都查询Auth服务(Keycloak -在我的情况下)不是一个好主意。因此,最好在本地验证签名,只要您的请求通过API网关传递到微服务。
所以,我想以这种方式设置我的Spring应用程序。

我说得对吗:

  1. jwt.jwk-set-uri参数负责在本地检查JWT键。因此,当我设置这个时,将从Keycloak的端点获取打开的密钥,以便将来离线检查JWT签名的有效性。每次检查都不进入Keycloak的服务器。
    1.如果我设置issuer-uri而不设置jwk-set-uri,那么每个请求都将只进行在线JWT检查。
    如果以上所述都是错误的,请描述你认为正确的方法。不幸的是,Spring's doc在这一点上并不冗长,它指出:
    因此,资源服务器在启动时不会ping授权服务器。我们仍然指定issuer-uri,以便ResourceServer仍然在传入的JWT上验证iss声明。
    我所说的配置在这里(application.yaml):
security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:3000/realms/msapp
          jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/protocol/openid-connect/certs

安全配置

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity()
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .csrf().disable()
            .authorizeExchange()
                .pathMatchers("/login").permitAll()
            .anyExchange()
                .authenticated().and()
            .oauth2ResourceServer() 
                .jwt()
                .jwtAuthenticationConverter(keykloakJwtAuthConverter());
        return http.build();
    }
x33g5p2x

x33g5p2x1#

单独使用时,issuer-uri有两个用途:

  • 发现OpenID配置(通常为{issuer-uri}/.well-known/openid-configuration),从中读取JWKS端点URI,然后获取公钥
  • 在JWT解码器中设置颁发者验证器:如果令牌中iss声明的值与配置的值不完全匹配,则会抛出异常(即使是尾随的斜杠,如果有的话,也很重要)。

当提供jwk-set-uri时,无论配置为issuer-uri(可以省略,在这种情况下,JWT解码器不会验证发行者),都会使用它获取公钥。**但是令牌仍然使用JWT解码器进行验证,所以当您认为设置jwk-set-uri时,每个请求都会往返于授权服务器时,您就错了。**当您使用访问令牌内省(而不是JWT解码)或如果您在身份验证转换器或管理器中显式连接它(例如使用REST客户端调用Keycloak的授权服务)时,就会发生这种往返。
在我看来,你应该验证发行者,因此,提供issuer-uri。在这种情况下,只有当由于网络配置的原因,资源服务器无法使用它设置为受众声明的内容访问授权服务器时,才需要提供jwk-set-uri(当授权服务器配置错误并将localhost URI作为容器化环境中的受众时,就会发生这种情况)。因此,在您的配置中(您重用issuer-uri来定义jwk-set-uri),只需删除jwk-set-uri,它将从OpenID配置中推断出来。
P.S.
正如已经写在另一个问题,你真的会保存时间和努力阅读我的教程:你的资源服务器配置仍然有一个引用/login(这是不应该的),CSRF保护被禁用,但会话仍被启用(这是一个非常糟糕的主意),你不是为未经授权的请求显式返回401(默认是302重定向到登录,这对资源服务器来说是没有意义的),没有任何关于CORS配置的内容,这是你可能会遇到的,最后,我猜你还没有写一个正式的keykloakJwtAuthConverter

b4wnujal

b4wnujal2#

根据文件:resource-server
资源服务器将使用此属性(issuer-uri:)进一步进行自我配置,发现授权服务器的公钥,并随后验证传入的JWT。
如果资源服务器必须能够独立于授权服务器启动,则可以提供jwk-set-uri
我想我给予回答你的问题更多的细节,阅读你自己的文档关于资源服务器提供以上有一个很好的解释与例子。

相关问题