English 中文(简体)
Spring Spring 3.0 和Kecloak的测试采集器: 我是否应当使用Kecloak集装箱进行部队或一体化试验?
原标题:TestContainers with Spring Boot 3.0 and Keycloak: Should I use Keycloak Container for Unit or Integration Tests?

我在为我的Hello世界申请探索“春天会”3 的试验会,该申请有安全的终端点。 过去,为了单位测试目的,我依赖模拟脚印。 然而,随着测试会的整合,我想知道采用最佳办法将关键波拉克纳入其中。

Specifically, I m unsure whether I should use the Keycloak Container for my unit tests or reserve it for integration tests. My understanding is that TestContainers are often used to provide real instances of external services, like databases, during integration testing. But would it also make sense to use a Keycloak Container for unit tests to ensure that the authentication and authorization aspects are thoroughly tested within the controlled environment of a container?

Could someone please provide insights into the pros and cons of using the Keycloak Container for both unit and integration tests in the context of Spring Boot 3.0? Additionally, any guidance on the best practices for incorporating Keycloak with TestContainers in different testing scenarios would be greatly appreciated.

Thank you!

Initial Test Case with Mockito

@Test     
void indexGreetsAuthenticatedUser() throws Exception {
    this.mockMvc.perform(get("/hello")
        .with(jwt().jwt((jwt) -> jwt.claim("client_id","testclient"))))
        .andExpect(content().string(containsString("Hello world")));     
}

New Code with Test Containers

@Test     
void indexGreetsAuthenticatedUser() throws Exception {
    RestAssured.given()
               .header("Authorization",getClientCredBearer()).when()
               .get("/hello").then().body(containsString("Hello world"));     
}

where getClientCredBearer() enables the keycloak container and calls the token endpoint to generate a client Credential token.

问题回答

我要说的是,“在单位测试期间,当然不使用试验集装箱”。 速度较慢:用测试集装箱,你需要签发有效标识、编码,然后在MockMvc申请职位处理器(.with(jwt)()(你使用)、WebClient mutators和测试说明直接建立Authentication

此外,经测试说明,在单位测试除<代码>@以外的其他组成部分时,你可以设定安全等级。 主计长。 例如:

@Service
public class SecuredService {
    @PreAuthorize("hasAuthority( NICE )")
    String nice() {
        return "Dear %s, glad to see you!".formatted(SecurityContextHolder.getContext().getAuthentication().getName());
    }
    
    @PreAuthorize("isAuthenticated()")
    String hello() {
        return "Hello %s.".formatted(SecurityContextHolder.getContext().getAuthentication().getName());
    }
}

有了测试集装箱,你需要请求建立安全环境,但在测试这种编号<>@service时,这毫无意义。

我不是MockMvc员额处理员,而是向以下网站提供了资料:。 I published in mers-addons-oauth2-

随附“我的”说明,你有不同的选择来测试上述服务(注:与Junnit 5 <代码>@Paraile的兼容性):

  • if defining just authorities (and maybe name and Authentication type to build), @WithMockAuthentication is probably enough:
@SpringBootTest(classes = { SecurityConfig.class, MessageService.class })
class MessageServiceTests {

    @Autowired
    private SecuredService securedService;
    
    @Test
    @WithMockAuthentication("BAD_BOY")
    void givenUserIsNotGrantedWithNice_whenCallNice_thenThrows() {
        assertThrows(Exception.class, () -> securedService.nice());
    }

    @Test
    @WithMockAuthentication(name = "brice", authorities = "NICE")
    void givenUserIsNice_whenCallNice_thenReturnsGreeting() {
        assertThat(securedService.nice()).isEqualTo("Dear brice, glad to see you!");
    }

    @ParameterizedTest
    @AuthenticationSource(
        @WithMockAuthentication(name = "brice", authorities = "NICE"),
        @WithMockAuthentication(name = "ch4mp", authorities = { "VERY_NICE", "AUTHOR" }))
    void givenUserIsAuthenticated_whenCallHello_thenReturnsGreeting(@ParameterizedAuthentication Authentication auth) {
        assertThat(securedService.hello()).isEqualTo("Hello %s.".formatted(auth.getName()));
    }
}
  • if you want a complete control on all claims, then @WithJwt (or @WithOpaqueToken if you re using introspection) might be better suited:
@AddonsWebmvcComponentTest // omit if you re not using the starter, this loads a minimal subset of spring-addons security conf
@SpringBootTest(classes = { SecurityConfig.class, MessageService.class })
class MessageServiceTests {

    @Autowired
    private SecuredService securedService;

    @Autowired
    WithJwt.AuthenticationFactory authFactory;
    
    @Test
    @WithJwt("igor.json")
    void givenUserIsIgor_whenCallNice_thenThrows() {
        assertThrows(Exception.class, () -> securedService.nice());
    }

    @Test
    @WithJwt("brice.json")
    void givenUserIsBrice_whenCallNice_thenReturnsGreeting() {
        assertThat(securedService.nice()).isEqualTo("Dear brice, glad to see you!");
    }

    @ParameterizedTest
    @MethodSource("identities")
    void givenUserIsAuthenticated_whenCallHello_thenReturnsGreeting(@ParameterizedAuthentication Authentication auth) {
        assertThat(securedService.hello()).isEqualTo("Hello %s.".formatted(auth.getName()));
    }

    Stream<AbstractAuthenticationToken> identities() {
        return authFactory.authenticationsFrom("brice.json", "igor.json");
    }
}

@WithJwt will search for an authentication converter in your security conf (a Converter<Jwt, ? extends AbstractAuthenticationToken> as you most probably have defined to turn Keycloak roles into Spring Security authorities) and use it to build an Authentication instance out of a JSON payload in the test class-ath (inspired by a JWT payload or introspection response). So basically, the Authentication instance should be the exact same as with a real authorization server delivering a token with the same claims (name, authorities, Authentication impl, etc.).





相关问题
凌驾于多租期的钥匙花 the?

so I have micro service application where one of those called auth_manager used to authenticate and register new user , I use the auth_manager to get token for user from keycloak , and other services ...

Add custom attribute in my keycloak client roles

I can add a custom attribute to my user following this link. I want to add a (common) custom attribute to my client roles. Is it possible? I tried to replicate the custom attribute like my user ...

Keycloak custom theme reject login.ftl

I create custom keycloak login screen. I download from keycloak web page Server Standalone server distribution And copy from keycloak-8.0.2 hemeskeycloak to C:xxconfigurationkeycloak...

WSO2 APIM 4.2 http gateaway mixed content error

I m using wso2 apim 4.2 with keycloak key manager to invoke an api through http. I published the api to get published through http and https, for the domain I already inject the ssl on wso2 apim. I ...

热门标签