【问题标题】:How to customize the jwt decoder in spring boot oauth2如何在spring boot oauth2中自定义jwt解码器
【发布时间】:2019-04-03 09:41:31
【问题描述】:

我想在我的资源服务器上为不同的租户动态设置 jwk-set-uri,我从过滤器中获取租户信息。我有以下资源服务器配置。

@Slf4j
@Import(SecurityProblemSupport.class)
@RequiredArgsConstructor
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

  private final SecurityProblemSupport problemSupport;
  private final RealmProperties realmProperties;
  private final MultiTenantManager multiTenantManager;

  @Override
  public void configure(final HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .exceptionHandling().authenticationEntryPoint(problemSupport).accessDeniedHandler(problemSupport)
      .and()
        .authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
      .and().requestMatcher(new OAuthRequestedMatcher()).authorizeRequests().anyRequest()
        .fullyAuthenticated();
  }

  @Bean
  public RequestContextListener requestContextListener() {
    return new RequestContextListener();
  }

  private static class OAuthRequestedMatcher implements RequestMatcher {

    public boolean matches(HttpServletRequest request) {
      String auth = request.getHeader("Authorization");
      log.debug("auth decode from request: ", auth);
      boolean haveOauth2Token = (auth != null) && auth.startsWith("Bearer");
      boolean haveAccessToken = request.getParameter("access_token") != null;
      return haveOauth2Token || haveAccessToken;
    }
  }

  @Override
  public void configure(final ResourceServerSecurityConfigurer config) {
    config.resourceId("login-app");
  }

  @Bean
  SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.authorizeExchange().anyExchange().authenticated().and().oauth2ResourceServer().jwt()
        .jwtDecoder(myCustomDecoder());
    return http.build();
  }

  @Bean
  ReactiveJwtDecoder myCustomDecoder() {
    return realmProperties.getRealms().stream()
    .filter(realm -> realm.getRealm().equals(multiTenantManager.getCurrentTenant()))
    .map(realm -> new NimbusReactiveJwtDecoder(((Realm) realm).getJwkSetUri()))
    .findFirst()
    .orElseThrow(() -> new InternalServerErrorException("cannot find the jwk set url for the realm"));
  }
}

但我有一个例外说

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.ObjectPostProcessor<?>' available

对此有任何帮助吗?我该怎么做才能动态设置 jwk set uri 来解析令牌?

谢谢 -彭

【问题讨论】:

    标签: spring spring-boot spring-security oauth-2.0


    【解决方案1】:

    我通过以下方式解决令牌解码的自定义:

    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        // Inject
        private String resourceId;
    
        // Inject
        private String secret;
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(resourceId);
            resources.tokenStore(createTokenStore(new ResourceAccessTokenConverter()));
        }
    
        private TokenStore createTokenStore(AccessTokenConverter converter) {
            JwtAccessTokenConverter tokenConverter = new CustomJwtAccessTokenConverter();
            tokenConverter.setAccessTokenConverter(converter);
            tokenConverter.setVerifier(new MacSigner(secret));
            TokenStore ts = new JwtTokenStore(tokenConverter);
    
            return ts;
        }
    
    
        public class CustomJwtAccessTokenConverter extends JwtAccessTokenConverter {
    
    
            @Override
            protected Map<String, Object> decode(String token) {
                return super.decode(token);
            }
    
            @Override
            public Map<String, ?> convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
                return super.convertAccessToken(token, authentication);
            }
    
            @Override
            public OAuth2AccessToken extractAccessToken(String value, Map<String, ?> map) {
                return super.extractAccessToken(value, map);
            }
    
            @Override
            public OAuth2Authentication extractAuthentication(Map<String, ?> map) {
                return super.extractAuthentication(map);
            }
    
        }
    
    }
    

    【讨论】:

    • 您能否详细说明此解决方案。我需要使用带有 NimbusJwtDecoderJwkSupport 的 Spring Security 5 进行测试。谢谢
    猜你喜欢
    • 2020-10-25
    • 2019-08-08
    • 2020-06-19
    • 2023-03-18
    • 1970-01-01
    • 2019-02-10
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多