如何在 Spring Boot 应用程序中测试 Keycloak 身份验证? [英] How to test Keycloak authentication in Spring Boot application?
问题描述
在 Spring Boot 项目中,我们启用了 Spring Security 并使用不记名令牌应用 Keycloak 身份验证,如以下文章所述:
In a Spring Boot project we enabled Spring Security and applied Keycloak authentication with bearer token like described in the following articles:
https://www.keycloak.org/docs/3.2/securing_apps/topics/oidc/java/spring-security-adapter.html
https://www.keycloak.org/docs/3.2/securing_apps/topics/oidc/java/spring-boot-adapter.html
但我找不到任何关于如何进行自动化测试以便应用 Keycloak 配置的建议.
But i can't find any recommendations how to make automation tests so that the Keycloak config is applied.
那么,当启用 Spring 安全性时,如何测试/模拟/验证 Keycloak 配置?一件非常烦人的事情:默认情况下 Spring 激活 csrf 安全过滤器,但如何避免测试呢?
So, how to test/mock/verify the Keycloak configuration when Spring security is enabled? One really annoying thing: by default Spring activates csrf security filter, but how to avoid testing it?
(注意:我们使用不记名令牌,所以看起来 @WithMockUser
在这种情况下不适用)
(Note: we use bearer tokens, so looks like @WithMockUser
is not applicable in this case)
一个额外的问题:基本上我们不想在每个控制器集成测试上验证安全性,所以是否可以与控制器集成测试分开验证安全性(那些使用 @SpringBootTest
、@WebAppConfiguration
、@AutoConfigureMockMvc
等等?
A bonus question:
basically we don't want to verify security on each controller integration test, so is it possible to verify security separately from the controllers integration tests (those which use @SpringBootTest
, @WebAppConfiguration
, @AutoConfigureMockMvc
and so on?
推荐答案
申请红利"的部分答案仅问题(@Component
单元测试):我刚刚写了一组库 简化安全 Spring 应用程序的单元测试.我只运行这样的测试和 e2e 测试(包括富客户端前端和实际授权服务器).
Partial answer applying to the "bonus" question only (@Component
unit-tests): I just wrote a set of libs to ease unit-testing of secured Spring apps. I only run such tests and e2e tests (including rich client front-end and actual authorization-server).
它包括一个 @WithMockKeycloackAuth
注释,以及 Keycloak 专用的 MockMvc
请求后处理器
It includes a @WithMockKeycloackAuth
annotation, along with Keycloak dedicated MockMvc
request post-processor
示例用法:
@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"),
otherClaims = @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")));
}
maven-central 提供了不同的库,根据您的用例选择以下之一(仅 @WithMockKeycloakAuth
或更多工具,例如 MockMvc fluent API):
Different libs are available from maven-central, choose one of following according to your use-case (solely @WithMockKeycloakAuth
or more tooling such as MockMvc fluent API):
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-security-oauth2-test-addons</artifactId>
<version>2.4.1</version>
<scope>test</scope>
</dependency>
或
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-security-oauth2-test-webmvc-addons</artifactId>
<version>2.4.1</version>
<scope>test</scope>
</dependency>
这篇关于如何在 Spring Boot 应用程序中测试 Keycloak 身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!