【问题标题】:Spring Security Unit Test With Csrf causes HttpServletResponse to not be found使用 Csrf 的 Spring Security Unit Test 导致找不到 HttpServletResponse
【发布时间】:2016-08-03 19:08:00
【问题描述】:

我在其他任何地方都找不到这个问题。

我的单元测试设置如下:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
//@DatabaseSetup("classpath:decks.xml")
@WebIntegrationTest
public class DeckControllerTest {
    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders
                .webAppContextSetup(context)
                .apply(springSecurity())
                .build();
    }

    @Test
    @WithMockUser
    public void addDeck_ShouldRedirectIfUserLoggedInAndPostsInvalidDeck() throws Exception {
        DeckbuilderForm form = new DeckbuilderForm();
        ObjectMapper mapper = new ObjectMapper();
        String queryString = mapper.convertValue(form, UriFormat.class).toString();
        mockMvc.perform(post("/decks")
            .with(csrf())
            .contentType(MediaType.ALL)
            .content(queryString)
        )
                .andExpect(status().is3xxRedirection())
                .andExpect(flash().attributeExists("flash"));
    }

    @Test
    @WithMockUser
    public void addDeck_ShouldBeOkWithValidInput() throws Exception {
        DeckbuilderForm form = sampleValidDeckbuilderForm();
        ObjectMapper mapper = new ObjectMapper();
        String queryString = mapper.convertValue(form, UriFormat.class).toString();

        mockMvc.perform(post("/decks")
            .with(csrf().useInvalidToken())
            .content(queryString)
        )
                .andExpect(status().is3xxRedirection());
    }
}

我在运行测试时收到以下堆栈跟踪:

java.lang.IllegalArgumentException:HttpServletRequest 属性 必须包含属性的 HttpServletResponse javax.servlet.http.HttpServletResponse

这来自 LazyCsrfTokenRepository 类:

private HttpServletResponse getResponse(HttpServletRequest request) {
    HttpServletResponse response = (HttpServletResponse) request
            .getAttribute(HTTP_RESPONSE_ATTR);
    if (response == null) {
        throw new IllegalArgumentException(
                "The HttpServletRequest attribute must contain an HttpServletResponse for the attribute "
                        + HTTP_RESPONSE_ATTR);
    }
    return response;
}

任何解决此问题的建议将不胜感激,我知道通常人们会使用 @ContextConfiguration 而不是 @SpringApplicationConfiguration 但我只能使用这种方法,因为我使用的是 Java Config 并且不想复制我的配置用于测试。

【问题讨论】:

    标签: spring spring-mvc junit spring-security mocking


    【解决方案1】:

    升级到 spring-boot 1.4 后我也遇到了同样的问题。问题是我的 pom 出于某种原因包含特定版本的 spring-security-test (4.0.2)。删除此特定版本后,该项目现在使用版本 4.1.1,从而解决了该问题。如果我查看 4.1.0 版 (https://github.com/spring-projects/spring-security/compare/4.1.0.RELEASE...master) 的发布提交,它包含对 spring-boot 1.4 的更新,所以这是有道理的。

    【讨论】:

    • 最近做了一些重大的重构,所以可能需要几天才能更新我的测试。我会让你知道情况如何。我目前将我的 spring-security-test 版本从 4.1.1 更改为 4.1.0。 (4.1.1引起的错误)
    • 在我的主要重构和使用新的 @WebMvcTest 注释之后现在似乎已经修复了,但我仍然想知道为什么 4.1.0 解决了我的问题,你提到它实际上是问题。
    • 我在使用 spring-security-test 4.0.4 时遇到了同样的问题。升级到 4.1.4 或 4.2.1 修复了它。 (使用 Spring Boot 1.4.3)
    猜你喜欢
    • 2022-11-26
    • 1970-01-01
    • 2016-05-07
    • 2017-03-06
    • 2016-08-02
    • 2018-09-01
    • 2017-05-02
    • 2014-11-29
    • 2016-09-01
    相关资源
    最近更新 更多