Java 为什么@SpringBootTest中的KeyClope安全约束未激活?我如何激活它们?

Java 为什么@SpringBootTest中的KeyClope安全约束未激活?我如何激活它们?,java,spring-boot,testing,keycloak,Java,Spring Boot,Testing,Keycloak,我正在构建一个新的微服务,并使用KeyClope的访问令牌对其进行保护。到目前为止,我已经成功地访问了端点/令牌/测试,只有使用Key斗篷的有效令牌才能访问,应用程序属性如下所示: keycloak.auth-server-url=http://localhost:8888/auth keycloak.realm=realm keycloak.resource=api keycloak.public-client=true keycloak.securityConstraints[0].auth

我正在构建一个新的微服务,并使用KeyClope的访问令牌对其进行保护。到目前为止,我已经成功地访问了端点/令牌/测试,只有使用Key斗篷的有效令牌才能访问,应用程序属性如下所示:

keycloak.auth-server-url=http://localhost:8888/auth
keycloak.realm=realm
keycloak.resource=api
keycloak.public-client=true
keycloak.securityConstraints[0].authRoles[0]=basic-token
keycloak.securityConstraints[0].securityCollections[0].name=secured by basic access token
keycloak.securityConstraints[0].securityCollections[0].patterns[0]=/*
当使用mvn spring boot:run启动项目时,这项功能可以正常工作(我使用spring boot starter、KeyClope spring boot starter和而不使用spring boot starter安全性,如果可能的话,我希望避免这种安全性

现在我编写一些测试是为了好玩,而keydove的安全约束根本不起作用,唯一的区别是,这个示例使用spring boot starter security手动进行了大量的KeyClope设置。为什么它只有在使用-security时才能在测试中工作?为什么我的方法似乎不起作用

我错过什么了吗

谢谢


编辑:

经过几个小时的调试,我终于找到了答案。问题是keydepot的身份验证(无论出于何种原因,lol)是在Tomcat阀门中完成的,而不是在过滤器中完成的。MockMvc没有经过servlet容器(及其阀门),因此它甚至从未达到要进行身份验证的程度


TestRestTemplate确实如此(如果您使用starter安全性,它也是一个过滤器而不是阀门).我不知道使用阀门而不是过滤器背后的设计决策,但您可以使用KeyClope starter的配置并使用TestRestTemplate进行测试,或者使用更“昂贵”的starter安全配置与MockMvc结合使用。

您需要在SecurityContext中使用模拟或实例设置身份验证e每个测试中的右键类型:
SecurityContextHolder.getContext().setAuthentication(身份验证)

我写了一套。它包括一个
@WithMockKeycloackAuth
注释,以及KeyClope专用
MockMvc
请求后处理器和
WebTestClient
配置器/修改器

示例
@WithMockKeycloackAuth
用法:

@RunWith(SpringRunner.class)
@WebMvcTest(controllers=GreetingController.class)
@进口({
ServletKey隐身AuthUnitTestingSupport.UnitTestConfig.class,
keydovepspringbootsampleapp.keydovepconfig.class})
//因为此示例位于非Spring BooKiPoCK项目的中间,所以KelCuxAdvices被隔离在
//application-keydeport.properties
@ActiveProfiles(“密钥斗篷”)
公共类迎宾控制器NotatedTest{
private static final String GREETING=“您好%s!您被授予了%s.”;
@蚕豆
消息服务消息服务;
@蚕豆
jwt译码器jwt译码器;
@自动连线
MockMVC支持api;
@以前
公共作废设置(){
当(messageService.greet(any())。然后回答(调用->{
final var auth=invocation.getArgument(0,Authentication.class);
返回String.format(问候语,auth.getName(),auth.getAuthories());
});
}
@试验
@用mockkeydapeauth
在未经授权人员身份验证的情况下,public void SenseCureDuroteIsForbidden()引发异常{
获取(“/secured route”).andExpect(status().isplanded());
}
@试验
@使用mockkeydepeauth({“授权人员”})
使用AuthorizedPersonnelThenseCureduloteiSok()进行身份验证时引发异常,则为public void{
获取(“/secured route”).andExpect(status().isOk());
}
@试验
@用mockkeydapeauth(
权限={“用户”、“授权人员”},
id=@IdTokenClaims(sub=“42”),
oidc=@OIDCST标准声明(
电子邮件=”ch4mp@c4-网站“,
emailVerified=true,
昵称=“东顿海盗”,
preferredUsername=“ch4mpy”),
accessToken=@keydapertAccessToken(
realmAccess=@keydoveaccess(角色={“TESTER”}),
authorization=@keydropeauthorization(
权限=@keydepospermission(rsid=“toto”,rsname=“trc”,scopes=“abracadabra”),
privateClaims=@ClaimSet(stringClaims=@StringClaim(name=“foo”,value=“bar”))
public void When NauthenticatedWithKeyClope AuthenticationTokenThenCangreet()引发异常时{
api.get(“/greet”)
.andExpect(状态().isOk())
.andExpect(content().string(startsWith(“Hello ch4mpy!您被授予了”))
.andExpect(content().string(包含字符串(“授权人员”))
.andExpect(content().string(containssString(“用户”))
.andExpect(content().string(containssstring(“TESTER”));
}
}
maven central提供了不同的LIB,请根据您的用例选择以下选项之一:


com.c4-soft.springaddons
spring-security-oauth2-test-addons
2.3.4
测试
com.c4-soft.springaddons
spring-security-oauth2-test-webmvc-addons
2.3.4
测试