Spring Rest文档文档oauth / oidc安全性不起作用

问题描述

设置:

Spring-Boot 2.3.3

Java 11

身份验证服务器:Keycloak 11

上下文:

我有一个使用Keycloak 11作为oidc / oauth身份验证/授权服务器的Spring-Boot应用程序。这很好用,我的测试也能用。现在,我想用spring rest文档来记录api,因为我非常喜欢测试驱动的api设计。

@Test
@Order(5)
@WithMockKeycloakAuth(authorities = "ROLE_owner")
void createProduct_RealmRoleOwner_HttpStatusCreated() throws Exception {

MvcResult response = mockmvc.perform(post(URL).contentType(MediaType.APPLICATION_JSON)
        .content(objectMapper.writeValueAsstring(testProductDto))
        .accept(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.created").isNumber())
        .andExpect(jsonPath("$.name").value(testProductDto.getName()))
        .andExpect(jsonPath("$.price").value(testProductDto.getPrice()))
        .andExpect(jsonPath("$.id").value(1L))
          .andDo(document("{method-name}",Preprocessors.preprocessRequest(),Preprocessors.preprocessResponse(
                            ResponseModifyingPreprocessors.replaceBinaryContent(),ResponseModifyingPreprocessors.limitJsonArrayLength(objectMapper),Preprocessors.prettyPrint()),responseFields(fieldWithPath("id").description("Id of the new product"),fieldWithPath("name").description("Name of the product"),fieldWithPath("price").description("Price of the new product"),fieldWithPath("created").description("Unix timestamp when the product was created")
                            )))
        .andReturn();

response = mockmvc.perform(get(URL + "/1"))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.created").isNumber())
        .andExpect(jsonPath("$.name").value(testProductDto.getName()))
        .andExpect(jsonPath("$.price").value(testProductDto.getPrice()))
        .andExpect(jsonPath("$.id").value(1L))
        .andReturn();

}

当我运行此测试时,该测试通过了,但未记录任何身份验证详细信息。因此,我添加标题,因为我的标题包含一个Authorization字段。

 @Test
    @Order(5)
    @WithMockKeycloakAuth(authorities = "ROLE_owner")
    void createProduct_RealmRoleOwner_HttpStatusCreated() throws Exception {


    MvcResult response = mockmvc.perform(post(URL).contentType(MediaType.APPLICATION_JSON).header("Authorization","Bearer dXNlcjpzZWNyZXQ=")
            .content(objectMapper.writeValueAsstring(testProductDto))
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.created").isNumber())
            .andExpect(jsonPath("$.name").value(testProductDto.getName()))
            .andExpect(jsonPath("$.price").value(testProductDto.getPrice()))
            .andExpect(jsonPath("$.id").value(1L))
              .andDo(document("{method-name}",Preprocessors.preprocessResponse(
                                ResponseModifyingPreprocessors.replaceBinaryContent(),fieldWithPath("created").description("Unix timestamp when the product was created")
                                )))
            .andDo(document("headers",requestHeaders(
                            headerWithName("Authorization").description("Bearer auth credentials"))))
            .andReturn();

    response = mockmvc.perform(get(URL + "/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.created").isNumber())
            .andExpect(jsonPath("$.name").value(testProductDto.getName()))
            .andExpect(jsonPath("$.price").value(testProductDto.getPrice()))
            .andExpect(jsonPath("$.id").value(1L))
            .andReturn();
}

在这里,我尝试使用虚拟标题。它以401失败。当我创建一个真实的Bearer令牌时,只要它没有过期,它就可以工作。当然,我无法始终在运行测试时创建Bearer令牌。如果我离开标题字段,则会得到一个异常,因为它在请求中丢失,因此无法记录。

问题:

如果我不添加标头字段,我会对认证过程的工作感到有些困惑。有人可以解释原因吗?

当我将测试与@SpringBoottest一起使用时,将加载整个应用程序上下文,并使用我的Spring安全过滤器链,因为我没有对其进行模拟。这可以解释为什么Bearer令牌过期时会被拒绝。当我使用vild时,spring rest docs将我需要进行身份验证的所有详细信息添加到单独的标头文件夹中。有没有一种方法可以创建没有有效Bearer令牌的标头文件夹?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)