使用Csrf进行Spring安全单元测试导致无法找到HttpServletResponse

时间:2016-08-03 19:08:01

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

我无法在其他任何地方找到这个问题。

我的单元测试设置如下:

@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());
    }
}

我在运行测试时收到以下stacktrace:

  

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并且不想复制我的配置用于测试。

1 个答案:

答案 0 :(得分:4)

升级到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的更新,所以它是有道理的。

相关问题