Login jsp form and spring security xml configuration look like:
<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"/>
Here is the test for form sumbission:
@Test
public void testLoginPostController() throws Exception {
Account account = new AccountBuilder("test", "test", "[email protected]", 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"));
}
But I'm getting: java.lang.AssertionError: Status expected:<302> but was:<404>
When I open login page in browser I see that the generated form is:
<form action="/SpringMvcExample/j_spring_security_check" method="POST">
Ok, I tried to change test to:
this.mockMvc.perform(post("/SpringMvcExample/j_spring_security_check").param("j_username", account.getUsername()).param("j_password", "test"))
But got the same result. At the same time, when I submit the login form in the browser, it redirects me to the public/index.htm
page, as exptect in test.
What am I doing wrong?
UPDATE: Spring Security 4 has added official Test Support. There is a section that describes testing with MockMvc in detail.
It sounds as though you have not added the Spring Security Filter to your MockMvc. For example:
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", "[email protected]", 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"));
}
}
The reason this is happening is because right now the MockMvc is only aware of your Spring MVC configuration and is not aware of any Filter (i.e. the FilterChainProxy). Since validation of the username and password (i.e. processing of /j_spring_security_check) occurs within FilterChainProxy before it is sent to Spring MVC and you have not included it you are getting a 404.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With