Probando el controlador de seguridad de Spring usando Spring Mvc Test

El formulario jsp de inicio de sesión y la configuración xml de seguridad de primavera se ven así:

<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"/>

Aquí está la prueba para la presentación de formularios:

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

Pero estoy obteniendo: java.lang.AssertionError: Status expected:<302> but was:<404>

Cuando abro la página de inicio de sesión en el navegador, veo que el formulario generado es:

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

Ok, traté de cambiar la prueba a:

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

Pero obtuve el mismo resultado. Al mismo tiempo, cuando envío el formulario de inicio de sesión en el navegador, me redirige a la public/index.htm página, como se esperaba en la prueba.

¿Qué estoy haciendo mal?

preguntado el 04 de diciembre de 13 a las 23:12

2 Respuestas

ACTUALIZACIÓN: Spring Security 4 ha agregado oficial Soporte de prueba. Hay una sección que describe probando con MockMvc en detalle.

Parece que no ha agregado el filtro de seguridad Spring a su MockMvc. Por ejemplo:

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"));
    }

}

La razón por la que esto sucede es porque en este momento MockMvc solo conoce su configuración de Spring MVC y no conoce ningún filtro (es decir, FilterChainProxy). Dado que la validación del nombre de usuario y la contraseña (es decir, el procesamiento de /j_spring_security_check) ocurre dentro de FilterChainProxy antes de enviarlo a Spring MVC y no lo ha incluido, está obteniendo un 404.

contestado el 07 de mayo de 15 a las 15:05

/j_spring_security_check es una dirección especial manejada por Spring Security (posiblemente a través de su filtro, pero no verifiqué esto). No es un controlador de solicitudes registrado con Spring MVC, por lo que no puede usar MockMVC para probarlo.

Deberá iniciar un contenedor de aplicación real y usar algo HttpClient o Selenium.

Respondido el 04 de diciembre de 13 a las 23:12

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.