最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to do integration testing in Spring Cloud Gateway and keycloak? - Stack Overflow

programmeradmin0浏览0评论

I wanted to add integration tests for my spring cloud gateway. I found test containers and using that I spin up two services, keycloak container and gateway. Now I can already get the access token using keycloak getauthServerUrl method but I can’t seem authenticate. My security config looks like:

@EnableWebFluxSecurity
public class SecurityConfig {

  @Bean
  public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.csrf(ServerHttpSecurity.CsrfSpec::disable);
    http.authorizeExchange(auth -> auth.anyExchange().authenticated()).oauth2Login(withDefaults())
        .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
    return http.build();
  }

}

I think I know why I cannot authenticate in tests because my security config expects to login through a login page and in my test I add access token as a header. What can I change in my config that it works both with login page and without?

I wanted to add integration tests for my spring cloud gateway. I found test containers and using that I spin up two services, keycloak container and gateway. Now I can already get the access token using keycloak getauthServerUrl method but I can’t seem authenticate. My security config looks like:

@EnableWebFluxSecurity
public class SecurityConfig {

  @Bean
  public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.csrf(ServerHttpSecurity.CsrfSpec::disable);
    http.authorizeExchange(auth -> auth.anyExchange().authenticated()).oauth2Login(withDefaults())
        .oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
    return http.build();
  }

}

I think I know why I cannot authenticate in tests because my security config expects to login through a login page and in my test I add access token as a header. What can I change in my config that it works both with login page and without?

Share Improve this question asked Mar 2 at 22:14 isaeedisaeed 154 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Testing with Keycloak in a container is end-to-end testing (which is slow). If using the authorization code flow, you'll need an end-to-end test framework like Protractor to manipulate the UI as if users were actually logging in.

You can write integration tests for your Spring backend without a test container and, more importantly, without the need to manipulate a UI. For that, use:

  • @SpringBootTest(webEnvironment = WebEnvironment.MOCK)
  • As you seem to be using the reactive version of Spring Cloud Gateway, @AutoConfigureWebTestClient (would be @AutoConfigureMockMvc in a servlet)
  • When using WebTestClient to query an oauth2ResourceServer configured with a JWT decoder and the default authentication converter, you can mock the JwtAuthenticationToken in the test's security context with SecurityMockServerConfigurers.mockJwt() (would be SecurityMockMvcRequestPostProcessors.jwt() with MockMvc). But as there are quite some limitations to WebTestClient mutators (and the MockMvc post-processors) I created in spring-security-tests for OAuth2, I also created test annotations in spring-addons-oauth2-tests.

I described that in details in this Baeldung article.

Side notes

Unit-test access control

If your aim is to test access control, you should consider writing unit tests with @WebFluxTest or WebMvcTest.

@SpringBootTest integration tests and end-to-end tests are slower than unit tests and should be used for testing no more than things wirering correctly together (not all possible access attempts for instance).

Configure Gateway with oauth2Login or no security at all

On a gateway, I would not configure the security filter chain for routes to downstream resource servers with oauth2ResourceServer. Instead:

  • when the API is consumed by a SPA or mobile app using the authorization code flow, I apply the OAuth2 BFF pattern: configure such a filter chain with oauth2Login and the routes with the TokenRelay= filter
  • when the API is consumed by an OAuth2 client, I either remove security from the gateway filter chain (and the TokenRelay= filter) for "routes" to downstream services, or I have OAuth2 clients query the downstream services directly (skip the gateway)

In both cases:

  • resources' access control is the responsibility of downstream resource servers
  • on the gateway, resources served by the gateway itself (actuator endpoints for instance) and by downstream services are not processed by the same filter chain
发布评论

评论列表(0)

  1. 暂无评论