4

登录 jsp 表单和 spring security xml 配置如下:

<spring:url value="/j_spring_security_check" var="login" />
<form action="${login}" method="POST">
<fieldset>
    <legend>Login</legend>
        <input type="text" name="j_username" id="username" placeholder="Usename"/>
        <input type="text" name="j_password" id="password" placeholder="Password"/>
        <input type="submit" value="Login" />
</fieldset>
</form>
...
<security:form-login login-page="/public/authentication/login.htm"
     login-processing-url="/j_spring_security_check"
     default-target-url="/public/index.htm"
     authentication-failure-url="/public/authentication/login.htm?authenticationNok=1"/>

这是表单汇总的测试:

@Test
public void testLoginPostController() throws Exception {
    Account account = new AccountBuilder("test", "test", "test@gmail.com", Address.FAKE_EMPTY_ADDRESS4TESTS)
            .build();
    this.mockMvc.perform(post("/j_spring_security_check").param("j_username", account.getUsername()).param("j_password", "test"))
            .andDo(print())
            .andExpect(status().isMovedTemporarily())
            .andExpect(view().name("redirect:/public/index.htm"));
}

但我得到:java.lang.AssertionError: Status expected:<302> but was:<404>

当我在浏览器中打开登录页面时,我看到生成的表单是:

<form action="/SpringMvcExample/j_spring_security_check" method="POST">

好的,我尝试将测试更改为:

this.mockMvc.perform(post("/SpringMvcExample/j_spring_security_check").param("j_username", account.getUsername()).param("j_password", "test"))

但是得到了同样的结果。同时,当我在浏览器中提交登录表单时,它会将我重定向到public/index.htm页面,正如测试中所期望的那样。

我究竟做错了什么?

4

2 回答 2

7

更新:Spring Security 4 添加了官方测试支持。有一节详细描述了使用 MockMvc进行测试。

听起来好像您还没有将 Spring Security Filter 添加到您的 MockMvc 中。例如:

public class MyTests {

    @Autowired
    private FilterChainProxy springSecurityFilterChain;

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webApplicationContextSetup(this.wac)
            .addFilters(this.springSecurityFilterChain).build();
    }

    @Test
    public void testLoginPostController() throws Exception {
        Account account = new AccountBuilder("test", "test", "test@gmail.com", Address.FAKE_EMPTY_ADDRESS4TESTS)
                .build();
        this.mockMvc.perform(post("/j_spring_security_check").param("j_username", account.getUsername()).param("j_password", "test"))
                .andDo(print())
                .andExpect(status().isMovedTemporarily())
                .andExpect(view().name("redirect:/public/index.htm"));
    }

}

发生这种情况的原因是因为现在 MockMvc 只知道您的 Spring MVC 配置并且不知道任何过滤器(即 FilterChainProxy)。由于用户名和密码的验证(即 /j_spring_security_check 的处理)发生在 FilterChainProxy 中,然后再发送到 Spring MVC 并且您没有包含它,因此您将获得 404。

于 2013-12-05T14:08:54.873 回答
0

/j_spring_security_check是 Spring Security 处理的一个特殊地址(可能通过它的过滤器,但我没有验证这一点)。它不是在 Spring MVC 中注册的请求处理程序,因此您不能使用 MockMVC 对其进行测试。

您需要启动一个真正的应用程序容器并使用 HttpClient 或 Selenium。

于 2013-12-04T23:44:01.267 回答