gpt4 book ai didi

spring - 模拟 Keycloak token 以测试 Spring Controller

转载 作者:行者123 更新时间:2023-12-04 12:45:24 24 4
gpt4 key购买 nike

我想为我的 spring Controller 编写单元测试。我正在使用 keycloak 的 openid 流程来保护我的端点。

在我的测试中,我使用了 @WithMockUser用于模拟经过身份验证的用户的注释。我的问题是我正在从主体的 token 中读取 userId。我的单元测试现在失败了,因为 userId我从 token 中读取为空;

        if (principal instanceof KeycloakAuthenticationToken) {
KeycloakAuthenticationToken authenticationToken = (KeycloakAuthenticationToken) principal;
SimpleKeycloakAccount account = (SimpleKeycloakAccount) authenticationToken.getDetails();
RefreshableKeycloakSecurityContext keycloakSecurityContext = account.getKeycloakSecurityContext();
AccessToken token = keycloakSecurityContext.getToken();
Map<String, Object> otherClaims = token.getOtherClaims();
userId = otherClaims.get("userId").toString();
}

有什么可以轻松模拟 KeycloakAuthenticationToken ?

最佳答案

@WithmockUser 使用 UsernamePasswordAuthenticationToken 配置安全上下文。这对于大多数用例来说都很好,但是当您的应用程序依赖另一个身份验证实现时(就像您的代码一样),您必须构建或模拟正确类型的实例并将其放入测试安全上下文中:SecurityContextHolder.getContext().setAuthentication(authentication);当然,你很快就会想要自动化这个,构建你自己的注释或 RequestPostProcessor... 或者 ...
拿一个“现成的”,就像这个 lib of mine ,它可以从 maven-central 获得:

<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-security-oauth2-test-webmvc-addons</artifactId>
<version>2.3.4</version>
<scope>test</scope>
</dependency>
您可以将它与 @WithMockKeycloackAuth 注释一起使用:
@RunWith(SpringRunner.class)
@WebMvcTest(GreetingController.class)
@ContextConfiguration(classes = GreetingApp.class)
@ComponentScan(basePackageClasses = { KeycloakSecurityComponents.class, KeycloakSpringBootConfigResolver.class })
public class GreetingControllerTests extends ServletUnitTestingSupport {
@MockBean
MessageService messageService;

@Test
@WithMockKeycloackAuth("TESTER")
public void whenUserIsNotGrantedWithAuthorizedPersonelThenSecretRouteIsNotAccessible() throws Exception {
mockMvc().get("/secured-route").andExpect(status().isForbidden());
}

@Test
@WithMockKeycloackAuth("AUTHORIZED_PERSONNEL")
public void whenUserIsGrantedWithAuthorizedPersonelThenSecretRouteIsAccessible() throws Exception {
mockMvc().get("/secured-route").andExpect(content().string(is("secret route")));
}

@Test
@WithMockKeycloakAuth(
authorities = { "USER", "AUTHORIZED_PERSONNEL" },
id = @IdTokenClaims(sub = "42"),
oidc = @OidcStandardClaims(
email = "ch4mp@c4-soft.com",
emailVerified = true,
nickName = "Tonton-Pirate",
preferredUsername = "ch4mpy"),
privateClaims = @ClaimSet(stringClaims = @StringClaim(name = "foo", value = "bar")))
public void whenAuthenticatedWithKeycloakAuthenticationTokenThenCanGreet() throws Exception {
mockMvc().get("/greet")
.andExpect(status().isOk())
.andExpect(content().string(startsWith("Hello ch4mpy! You are granted with ")))
.andExpect(content().string(containsString("AUTHORIZED_PERSONNEL")))
.andExpect(content().string(containsString("USER")));
}
或者 MockMvc fluent API(RequestPostProcessor):
@RunWith(SpringRunner.class)
@WebMvcTest(GreetingController.class)
@ContextConfiguration(classes = GreetingApp.class)
@ComponentScan(basePackageClasses = { KeycloakSecurityComponents.class, KeycloakSpringBootConfigResolver.class })
public class GreetingControllerTest extends ServletKeycloakAuthUnitTestingSupport {
@MockBean
MessageService messageService;

@Test
public void whenUserIsNotGrantedWithAuthorizedPersonelThenSecretMethodIsNotAccessible() throws Exception {
mockMvc().with(authentication().roles("TESTER")).get("/secured-method").andExpect(status().isForbidden());
}

@Test
public void whenUserIsGrantedWithAuthorizedPersonelThenSecretMethodIsAccessible() throws Exception {
mockMvc().with(authentication().roles("AUTHORIZED_PERSONNEL")).get("/secured-method")
.andExpect(content().string(is("secret method")));
}

}

关于spring - 模拟 Keycloak token 以测试 Spring Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49144953/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com