我知道关于这个问题已经有类似的问题,here和here,但是提出的每一个解决方案都无法帮助我。在大多数答案中也都提到了this库,但是(出于所有应有的尊重)我想避免依赖外部库只是为了测试一个简单的控制器。
因此,我有一个非常简单的api,可以使用keycloak生成的承载令牌来访问它,我想测试控制器。遵循以下原则:
@Test
@DisplayName("Should be ok")
@WithMockUser
void whenCalled_shouldBeOk() throws Exception {
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
mockMvc.perform(
post("/api/url/something")
.content("{}")
.contentType(APPLICATION_JSON)
.with(authentication(authentication))
).andExpect(status().isOk());
}
问题是我总是会收到KeycloakDeploymentBuilder
抛出的空指针异常,因为它缺少适配器配置。在我们的SecurityConfig中,我们扩展了KeycloakWebSecurityConfigurerAdapter
并完成了应用程序运行所需的所有必需配置,但是我无法在测试中模拟/绕过此过程。通常,我会在带有@WithMockUser批注的测试中找到解决身份验证问题的方法(当不使用keycloak时),但是这次却没有。
不是要模拟适配器或过滤器过程来绕过此问题的方法吗?
我尝试了在其他问题(图书馆除外)中回答的所有问题,但是没有运气。如果您有任何帮助的线索,或者至少可以为我指明正确的方向(因为这可能是由于我缺乏对弹簧安全性的了解),那么将不胜感激。
答案 0 :(得分:0)
正如我在回答您所链接的第一个问题的答案中所写的那样,当您的代码/ conf可能期望使用@WithMockUser
时,UsernamePaswordAuthenticationToken
用KeycloakAuthenticationToken
填充安全上下文。
如果您仔细阅读了相同的答案,您将找到使用我的lib的替代方法:使用KeycloakAuthenticationToken
实例手动填充安全上下文或在每个测试中模拟。
最小样本与Mockito I added to my repo:
@Test
public void test() {
final var principal = mock(Principal.class);
when(principal.getName()).thenReturn("user");
final var account = mock(OidcKeycloakAccount.class);
when(account.getRoles()).thenReturn(Set.of("offline_access", "uma_authorization"));
when(account.getPrincipal()).thenReturn(principal);
final var authentication = mock(KeycloakAuthenticationToken.class);
when(authentication.getAccount()).thenReturn(account);
// post(...).with(authentication(authentication))
// limits to testing secured @Controller with MockMvc
// I prefer to set security context directly instead:
SecurityContextHolder.getContext().setAuthentication(authentication);
//TODO: invoque mockmvc to test @Controller or test any other type of @Component as usual
}
也许,在您确定这会使您的测试杂乱无章(此处设置的声明很少)后,您将重新考虑使用我的lib(或从它的开源版本复制它)。
使用我的注释,上面的示例变为:
@Test
@WithMockKeycloakAuth
public void test() throws Exception {
//TODO: invoque mockmvc to test @Controller or test any other type of @Component as usual
}
关于涉及Keycloak的弹簧测试配置,您可以深入研究spring-security-oauth2-test-webmvc-addons
模块的测试。您会发现一个complete app using KeycloakAuthenticationToken
带有单元测试(和有效的测试配置)