spring-test-mvc junit testing Spring Security layer with InMemoryDaoImpl

For people in hurry here is the code sample and the steps to setup the code.

Spring Security 3.1 is a framework that supports authentication and authorization in Java. Spring MVC has a good integration with Spring Security. In this blog, I will demonstrate how to JUnit test Spring Security layer for a Spring MVC application using spring-test-mvc.

The usecase we use in this blog is a Spring MVC based calendar application, where user can login and enter his events his events. User can see other user events but he cannot change it. An admin user can see other user’s Events as well as change it.

To enable spring-test-mvc, we need to setup spring-test-mvc. As a first setp get the latest code from github. and run the “mvn install” command in the downloaded folder. After that we need to add the below dependency in the pom.xml,

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test-mvc</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<scope>test</scope>
</dependency>

For a starter I will start writing the JUnit test as below to capture above usecase,

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

@Test
public void testIndex() throws Exception {
mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(forwardedUrl("/WEB-INF/views/index.jsp"));
}

@Test
public void testEventsNonAdmin() throws Exception {
mockMvc.perform(get("/events/").with(userDeatilsService("user1@example.com"))).andExpect(status().isForbidden());
}

@Test
public void testEventsAdminLogin() throws Exception {
mockMvc.perform(get("/events/").with(userDeatilsService("admin1@example.com"))).andExpect(status().isOk());
}

@Test
public void testMyEvents() throws Exception {
mockMvc.perform(get("/events/my").with(userDeatilsService("user1@example.com"))).andExpect(status().isOk());
}

@Test
public void testShow() throws Exception {
mockMvc.perform(get("/events/100").with(userDeatilsService("user1@example.com"))).andExpect(status().isOk());
}

@Test
public void testCreateEventForm() throws Exception {
mockMvc.perform(
post("/events/new").param("attendeeEmail", "user1@example.com").param("summary", "krishna").param("description", "whatever")
.param("when", "2012-01-01 01:02").with(userDeatilsService("user1@example.com"))).andExpect(status().isOk())
.andExpect(redirectedUrl("/events/my"));
}

To wire Spring Security with JUnit test you need to do as below,

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = WebContextLoader.class, value = {
"classpath:/META-INF/spring/video1-spring-inmemory-userdetailservice-config/services.xml",
"classpath:/META-INF/spring/video1-spring-inmemory-userdetailservice-config/security.xml",
"classpath:/META-INF/spring/video1-spring-inmemory-userdetailservice-config/mvc-config.xml" })
public class Video1SpringInmemoryUserdetailServiceControllerTest {

The Spring security config file looks as below,

<http pattern="/resources/**" security="none"/>
<http auto-config="true" use-expressions="true" create-session="ifRequired">
<intercept-url pattern="/" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')"/>
<intercept-url pattern="/login/*" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')"/>
<intercept-url pattern="/logout" access="hasRole('ROLE_ANONYMOUS') or hasRole('ROLE_USER')"/>
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/events/" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>

<form-login login-page="/login/form"
login-processing-url="/login" username-parameter="username" password-parameter="password"
authentication-failure-url="/login/form?error"/>
<logout logout-url="/logout" logout-success-url="/login/form?logout"/>
</http>

<authentication-manager>
<authentication-provider>
<user-service>
<user name="user1@example.com" password="user1" authorities="ROLE_USER"/>
<user name="admin1@example.com" password="admin1" authorities="ROLE_USER,ROLE_ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>

In this configuration there are 2 blocks one is http block that describes authentication and authentication-manager that describes authorization. In this example, for authorization we are using org.springframework.security.core.userdetails.memory.InMemoryDaoImpl helper class. To make this example work run the below command,


mvn clean test -Dtest=com.example.springsecurity.web.controllers.Video1SpringInmemoryUserdetailServiceControllerTest

In my next blog I will be introducing Jdbc implementation of authorization.

REFERENCE

Spring Security 3.1 by Robert Winch and Peter Mularien

About these ads

7 thoughts on “spring-test-mvc junit testing Spring Security layer with InMemoryDaoImpl

  1. Pingback: Spring Security Certificate Authentication Authorization Example | Krishna's Blog

  2. Pingback: spring-test-mvc junit testing Spring Security layer with JdbcDaoImpl | Krishna's Blog

  3. Pingback: spring-test-mvc junit testing Spring Security layer with LDAP | Krishna's Blog

  4. Pingback: spring-test-mvc junit testing Spring Security layer with Method level Security | Krishna's Blog

  5. Pingback: Sample of Spring Security and CAS (Single Signon) | Krishna's Blog

  6. Pingback: JUnit testing of Spring MVC application: Testing Controller | Krishna's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s