java - MVC 测试 Spring Boot 模拟 Keycloak 令牌
问题描述
我正在尝试使用 keycloak 安全 API 为我做一个 MVC-Unittest。
使用https://github.com/ch4mpy/spring-addons,根据示例,测试应该可以正常工作。
测试:
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = StudentController.class)
@AutoConfigureMockMvc
@Import({ServletKeycloakAuthUnitTestingSupport.UnitTestConfig.class,
KeycloakSecurityConfig.class})
public class StudentControllerTests {
@Autowired
private MockMvc mockMvc;
@MockBean
private StudentService service;
@MockBean
private StudentRepository repository;
//TODO: Fix keycloak bug
@Test
@WithMockKeycloakAuth(
authorities = { "USER", "AUTHORIZED_PERSONNEL" },
id = @IdTokenClaims(sub = "42"),
oidc = @OidcStandardClaims(
email = "test@testing.com",
emailVerified = true,
nickName = "TesterNickName",
preferredUsername = "testName"),
accessToken = @KeycloakAccessToken(
realmAccess = @KeycloakAccess(roles = { "TESTER" }),
authorization = @KeycloakAuthorization(
permissions = @KeycloakPermission(rsid = "toto", rsname = "truc", scopes = "abracadabra"))),
privateClaims = @ClaimSet(stringClaims = @StringClaim(name = "foo", value = "bar")))
public void shouldTest() throws Exception {
MvcResult result = this.mockMvc.perform(get("/students/test")).andReturn();
assertEquals("abc", result.getResponse().getContentAsString());
}
}
应用程序.yml
keycloak:
realm: xxx
auth-server-url: http://localhost:8081/auth
ssl-required: external
resource: client-interface
use-resource-role-mappings: true
credentials:
secret: xxx
bearer-only: true
principal-attribute: preferred_username
我得到以下堆栈跟踪:
java.lang.NullPointerException
at org.keycloak.adapters.KeycloakDeploymentBuilder.internalBuild(KeycloakDeploymentBuilder.java:57)
at org.keycloak.adapters.KeycloakDeploymentBuilder.build(KeycloakDeploymentBuilder.java:202)
at org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver.resolve(KeycloakSpringBootConfigResolver.java:39)
at org.keycloak.adapters.springsecurity.config.KeycloakSpringConfigResolverWrapper.resolve(KeycloakSpringConfigResolverWrapper.java:40)
at org.keycloak.adapters.AdapterDeploymentContext.resolveDeployment(AdapterDeploymentContext.java:89)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:82)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
[...]
知道如何解决吗?
问候,罗萨里奥
解决方案
实时调频
根据堆栈跟踪,适配器配置在KeycloakDeploymentBuilder
. 跳了几跳后,似乎没有注入KeycloakSpringBootConfigResolver
.
正如我的lib 主自述文件中所述:“由于从 9.0.2 到 12.0.0 的回归,您必须实施一种解决方法,如 KeycloakSpringBootSampleApp 中所示”
在链接的示例中:
// Work-around https://issues.redhat.com/browse/KEYCLOAK-14520 until keycloak 12.0.0
@Configuration
public class SpringBootKeycloakConfigResolver implements KeycloakConfigResolver {
private KeycloakDeployment keycloakDeployment;
private AdapterConfig adapterConfig;
@Autowired
public SpringBootKeycloakConfigResolver(AdapterConfig adapterConfig) {
this.adapterConfig = adapterConfig;
}
@Override
public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
if (keycloakDeployment != null) {
return keycloakDeployment;
}
keycloakDeployment = KeycloakDeploymentBuilder.build(adapterConfig);
return keycloakDeployment;
}
}
推荐阅读
- flutter - 颤振 FutureBuilder 到 states_rebuilder
- react-native - useDispatch 钩子的问题 - React Native/Redux
- javascript - 将单个对象解构为多个对象的数组
- bash - 在 bash 中尝试逻辑比较
- selenium - 如何为 selenium 解析 xpath 抛出 org.openqa.selenium.InvalidSelectorException
- node.js - 443 端口上的 Socket.io
- javascript - 如何在制表器中为整列设置单元格值
- android - 以编程方式在 Android 应用程序中使用 Youtube 迷你播放器
- python - 字符串消息类型抛出 TypeError:字符串索引必须是整数
- android - 如何解决问题 SQLiteException: no such table: Cars (code 1 SQLITE_ERROR): , while compile: SELECT DISTINCT * FROM Cars?