【问题标题】:Oauth2 jwt token enriched with userinfo enpoint使用 userinfo 端点丰富的 Oauth2 jwt 令牌
【发布时间】:2023-02-01 05:53:20
【问题描述】:

我有一个公开一些 webflux 端点的 spring 应用程序,我使用 jwt 令牌来授权 post 调用,但我们还需要 userinfo 端点提供的信息。 我现在有一个 SecurityWebFilterChain bean,我们正在使用 oauth2ResourceServer 配置,然后调用 userinfoendpoint 进行进一步检查。 验证 jwt 令牌然后获取 userinfo enpoint 信息以进行进一步验证的最佳方法是什么?

ps:授权服务器是第三方的。

无需外部调用用户信息的安全配置

  @Bean
  public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {

    http
      .cors()
      .and()
            .httpBasic().disable()
            .formLogin().disable()
            .csrf().disable()
            .logout().disable()
            .oauth2Client()
            .and()
      .authorizeExchange()
            .pathMatchers(HttpMethod.POST).authenticated()
            .anyExchange().permitAll()
            .and().oauth2ResourceServer().jwt()
            ;

    return http.build();
  }

【问题讨论】:

  • 当你说“进一步验证”时,你能举个例子吗?
  • 通过不使用 JWT 而是使用不透明的令牌而不是构建一些奇怪的自定义流程。
  • @SteveRiesenberg 我们需要从用户信息端点响应中获取一个字段,将其映射并将其添加到权限

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


【解决方案1】:

UserInfo EndpointOpenID Connect 1.0 的一部分,返回访问令牌的用户信息。 Spring Security 不会自动从资源服务器 (http.oauth2ResourceServer()) 调用它。

根据您的安全配置,您似乎想在同一应用程序中同时使用 OAuth2 客户端 (http.oauth2Client()) 和 OAuth2 资源服务器 (http.oauth2ResourceServer())。 OAuth2 Client 不是为这种用例设计的(从资源服务器调用 UserInfo),因此需要定制以适应这种情况。相反,您可以简单地使用 RestTemplateWebClient 自己调用 UserInfo 端点。

您可以在自定义 Converter<Jwt, Collection<GrantedAuthority>> 中执行此操作,如下所示:

@Configuration
@EnableWebSecurity
public class ResourceServerConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authorize) -> authorize
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer((oauth2) -> oauth2
                .jwt((jwt) -> jwt
                    .jwtAuthenticationConverter(jwtAuthenticationConverter())
                )
            );
        return http.build();
    }

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

    private Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter() {
        JwtGrantedAuthoritiesConverter delegate = new JwtGrantedAuthoritiesConverter();
        return (jwt) -> {
            Collection<GrantedAuthority> authorities = delegate.convert(jwt);
            String accessToken = jwt.getTokenValue();
            // TODO: Use accessToken to call UserInfo endpoint and add authority
            return authorities;
        };
    }

}

【讨论】:

    猜你喜欢
    • 2015-04-22
    • 2017-10-11
    • 1970-01-01
    • 2013-01-25
    • 2015-04-16
    • 1970-01-01
    • 2023-02-15
    • 1970-01-01
    • 2018-08-03
    相关资源
    最近更新 更多