在使用凭据流时,如何使用OAuth2编写IntetGration测试Spring Web客户端(Spring MVC)

发布于 2025-02-11 15:27:10 字数 5722 浏览 1 评论 0原文

我有一个 oauth 2客户端,它实际上与另一个用作授权服务器的微服务(auth-server)交互。 我有一个端点(使用Spring MVC)。 的注释

@PreAuthorize("has Scope(T(.........).
@Configuration
public class AuthWebClientConfiguration {
    @Bean
    public OAuth2AuthorizedClientManager authorizedManager(
        ClientRegistrationRepository client,
        OAuth2AuthorizedClientRepository authorizedClient
    ) {
        OAuth2AuthorizedClientProvider authorizedProvider =
            OAuth2AuthorizedClientProviderBuilder
                .builder()
                .authorizationCode()
                .refreshToken()
                .clientCredentials()
                .build();

        DefaultOAuth2AuthorizedClientManager authorizedManager =
            new DefaultOAuth2AuthorizedClientManager(
                client,
                authorizedClient
            );

        authorizedClientManager.setAuthorizedClientProvider(authorizedProvider);

        return authorizedManager;
    }

    @Bean
    public ServletOAuth2AuthorizedClientExchangeFilterFunction oauthClient(OAuth2AuthorizedClientManager authorizedManager) {
        return new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedManager);
    }
}

@Service
@RequiredArgsConstructor
public class AuthClientManager {

    public static final String SERVICE_ID = "my-service";
    private final OAuth2AuthorizedClientManager oAuth2Manager;
    private final ServletOAuth2AuthorizedClientExchangeFilterFunction
        filterFunction;
    private final WebClient webClient;
    private WebClient client;

    public WebClient getClient() {
        return Optional.ofNullable(client)
            .orElseGet(() -> {
                OAuth2AuthorizeRequest authorizeRequest =
                    OAuth2AuthorizeRequest.withClientRegistrationId(SERVICE_ID)
                    .principal(SERVICE_ID)
                    .build();
                client = webClient
                    .mutate()
                    .filter(
                        (request, next) -> next
                            .exchange(
                                ClientRequest.from(request)
                                    .attributes(
                                        oauth2AuthorizedClient(
                                            oAuth2Manager.authorize(authorizeRequest)
                                        )
                                    ).build()
                            )
                    )
                    .apply(filterFunction.oauth2Configuration())
                    .build();
                return client;
            });
    }
}
  • 端点
@RequestMapping("email")
public interface RestController {

    @PreAuthorize("hasScope(T(......MESSAGE_SEND)")
   
    @PostMapping("v1/message")
    ResponseEntity<Void> send(@Valid @RequestBody Dto dto);
}
  • 实现
@RestController
@RequiredArgsConstructor
@Slf4j
public class RestControllerImpl implements RestController {

   
    @Override
    public ResponseEntity<Void> send(Dto dto) {


       return new ResponseEntity<>(HttpStatus.OK);
    }
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
@RequiredArgsConstructor
public class SecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new ScopeAwareExpressionHandler();
    }

    @Bean
    @Order(0)
    SecurityFilterChain apiFilterChain(
        HttpSecurity http,
        @Value("${spring.security.oauth2.client.provider-uri}") String hostname
    ) throws Exception {

        

        return http
            .cors()
            .configurationSource(request ->
                new CorsConfiguration()
                    .applyPermitDefaultValues()
            )
            .and()
            .csrf().disable()
            .requestMatchers(
                requestMatcherConfigurer -> requestMatcherConfigurer.antMatchers("/**")
            )
            .authorizeRequests(authorizeRequestsCustomized -> authorizeRequestsCustomized
                .antMatchers(
                    "/swagger-ui/**"
                )
                .permitAll()
                .anyRequest()
                .authenticated()
            )
            .oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer ->
                httpSecurityOAuth2ResourceServerConfigurer
                    .jwt()
                    .jwkSetUri(hostname + "/oauth2/jwks")
            )
            .build();
    }
}

  • 它具有端点应用程序
spring:
  security:
    oauth2:
      client:
        registration:
          my-service: # my-service
            provider: spring
            client-id: 1
            client-secret:1
            authorization-grant-type: client_credentials
            scope: message.send
            client-name: 1
        provider:
          spring:
            issuer-uri:locachost....
            user-info-uri: locachost..../api/v1/users/me
            user-name-attribute: id

。YAMLA希望为此端点编写集成测试,以验证 oauth2 client for cordentials flow flow 是否正确配置。好吧,一方面是我终点的工作。

我该怎么办?

我没有找到任何适合我任务的例子。

有人可以分享有关此案的知识吗?

I have an Oauth 2 client that actually interacts with another microservice that acts as an authorization server (auth-server).
I have an endpoint (use spring mvc). It has the annotation

@PreAuthorize("has Scope(T(.........).
@Configuration
public class AuthWebClientConfiguration {
    @Bean
    public OAuth2AuthorizedClientManager authorizedManager(
        ClientRegistrationRepository client,
        OAuth2AuthorizedClientRepository authorizedClient
    ) {
        OAuth2AuthorizedClientProvider authorizedProvider =
            OAuth2AuthorizedClientProviderBuilder
                .builder()
                .authorizationCode()
                .refreshToken()
                .clientCredentials()
                .build();

        DefaultOAuth2AuthorizedClientManager authorizedManager =
            new DefaultOAuth2AuthorizedClientManager(
                client,
                authorizedClient
            );

        authorizedClientManager.setAuthorizedClientProvider(authorizedProvider);

        return authorizedManager;
    }

    @Bean
    public ServletOAuth2AuthorizedClientExchangeFilterFunction oauthClient(OAuth2AuthorizedClientManager authorizedManager) {
        return new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedManager);
    }
}

@Service
@RequiredArgsConstructor
public class AuthClientManager {

    public static final String SERVICE_ID = "my-service";
    private final OAuth2AuthorizedClientManager oAuth2Manager;
    private final ServletOAuth2AuthorizedClientExchangeFilterFunction
        filterFunction;
    private final WebClient webClient;
    private WebClient client;

    public WebClient getClient() {
        return Optional.ofNullable(client)
            .orElseGet(() -> {
                OAuth2AuthorizeRequest authorizeRequest =
                    OAuth2AuthorizeRequest.withClientRegistrationId(SERVICE_ID)
                    .principal(SERVICE_ID)
                    .build();
                client = webClient
                    .mutate()
                    .filter(
                        (request, next) -> next
                            .exchange(
                                ClientRequest.from(request)
                                    .attributes(
                                        oauth2AuthorizedClient(
                                            oAuth2Manager.authorize(authorizeRequest)
                                        )
                                    ).build()
                            )
                    )
                    .apply(filterFunction.oauth2Configuration())
                    .build();
                return client;
            });
    }
}
  • endpoint
@RequestMapping("email")
public interface RestController {

    @PreAuthorize("hasScope(T(......MESSAGE_SEND)")
   
    @PostMapping("v1/message")
    ResponseEntity<Void> send(@Valid @RequestBody Dto dto);
}
  • implementation of endpoint
@RestController
@RequiredArgsConstructor
@Slf4j
public class RestControllerImpl implements RestController {

   
    @Override
    public ResponseEntity<Void> send(Dto dto) {


       return new ResponseEntity<>(HttpStatus.OK);
    }
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
@RequiredArgsConstructor
public class SecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new ScopeAwareExpressionHandler();
    }

    @Bean
    @Order(0)
    SecurityFilterChain apiFilterChain(
        HttpSecurity http,
        @Value("${spring.security.oauth2.client.provider-uri}") String hostname
    ) throws Exception {

        

        return http
            .cors()
            .configurationSource(request ->
                new CorsConfiguration()
                    .applyPermitDefaultValues()
            )
            .and()
            .csrf().disable()
            .requestMatchers(
                requestMatcherConfigurer -> requestMatcherConfigurer.antMatchers("/**")
            )
            .authorizeRequests(authorizeRequestsCustomized -> authorizeRequestsCustomized
                .antMatchers(
                    "/swagger-ui/**"
                )
                .permitAll()
                .anyRequest()
                .authenticated()
            )
            .oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer ->
                httpSecurityOAuth2ResourceServerConfigurer
                    .jwt()
                    .jwkSetUri(hostname + "/oauth2/jwks")
            )
            .build();
    }
}

  • application.yaml
spring:
  security:
    oauth2:
      client:
        registration:
          my-service: # my-service
            provider: spring
            client-id: 1
            client-secret:1
            authorization-grant-type: client_credentials
            scope: message.send
            client-name: 1
        provider:
          spring:
            issuer-uri:locachost....
            user-info-uri: locachost..../api/v1/users/me
            user-name-attribute: id

A would like to write an integration test for this endpoint to verify that the Oauth2 client for Credentials flow is configured correctly. well, for one thing, the work of my endpoint.

How could I do that ?

I have not found any examples suitable for my task.

Could someone share knowledge about this case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

原来分手还会想你 2025-02-18 15:27:10

如果要编写集成测试:

  • 启动授权服务器
  • 脚本查询以获取使用WebClient的授权令牌或
  • 设置测试请求授权标题,则使用您获得的Bearer令牌。

我宁愿使用@webmvctest或@webfluxtest bfluxtest编写单元测试,并使用spring-security-test或@withmockjwtauth从 https://github.com/ch4mpy/spring-addons

If you want to write integration test:

  • start authorization server
  • script query to get authorization token with WebClient or something
  • set test request Authorization header with bearer token you got.

I'd rather write unit tests with @WebmvcTest or @WebfluxTest bfluxTest and configure test security context with jwt() MockMvc post processor (or Word bTestClient mutator) from spring-security-test or @WithMockJwtAuth from https://github.com/ch4mpy/spring-addons

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文