Testing authentication and authorization is essential for securing Spring applications. Spring Security and JUnit allow developers to test user access, roles, and permissions by simulating authentication scenarios such as valid users, invalid users, and insufficient roles without running the entire application.
- Tests secured methods without deploying the application.
- Simulates authenticated users programmatically.
- Validates role-based access control (RBAC).
Important Concepts
- SecurityContextHolder: SecurityContextHolder stores the authentication and security information of the currently logged-in user.
- Authentication Object: Authentication represents the currently authenticated user and contains their username, password (or credentials), and granted authorities.
- UserDetailsService: UserDetailsService is an interface that loads user details such as username, password, and roles during authentication.
- @Secured Annotation: @Secured is used to restrict access to methods based on the roles assigned to the authenticated user.
- JUnit Testing: JUnit is a testing framework used to verify the authentication, authorization, and overall security functionality of Spring applications.
Step-by-Step Implementation
Step 1: Create a Maven Project
- Creates a basic Maven project.
- Generates standard project structure.
Create a Maven project using the following command:
mvn archetype:generate \
-DgroupId=com.geeksforgeeks \
-DartifactId=SpringPasswordHashingDemo \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false

Step 2: Add Required Dependencies
To make project eclipse supported, edit the pom.xml with the following dependencies and run the command mvn:eclipse:eclipse.
File: pom.xml
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.geeksforgeeks</groupId>
<artifactId>SpringPasswordHashingDemo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringPasswordHashingDemo</name>
<url>http://maven.apache.org</url>
<properties>
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
</properties>
<dependencies>
<!-- Spring Core -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${org.springframework.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${org.springframework.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${org.springframework.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${org.springframework.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
Step 3: Configure Spring Security
Create application-security.xml.
- Enables method-level security.
- Creates in-memory users
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security/"
xmlns:beans="http://www.springframework.org/schema/beans/"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans/
http://www.springframework.org/schema/beans//spring-beans-3.0.xsd
http://www.springframework.org/schema/security/
http://www.springframework.org/schema/security//spring-security-3.0.3.xsd">
<global-method-security secured-annotations="enabled" />
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="geeksforgeeks" password="password1" authorities="ROLE_USER" />
<user name="geeksforgeeks2" password="password2" authorities="ROLE_ADMIN" />
</user-service>
</authentication-provider>
</authentication-manager>
<beans:bean id="demoService" class="com.geeksforgeeks.DemoService"/>
</beans:beans>
Step 4: Create a Secured Service
Create DemoService.java.
- Demonstrates method-level security.
- Accessible only by users having ROLE_USER.
package com.geeksforgeeks;
// Importing required classes
import org.springframework.security.access.annotation.Secured;
// Class
public class DemoService {
@Secured("ROLE_USER")
// Method
public void method()
{
// Print statement
System.out.println("Method called");
}
}
Step 5: Create JUnit Test Class
Create TestDemoService.java.
- Loads Spring Security configuration.
- Creates authentication objects.
package com.geeksforgeeks;
// Importing required classes
import java.util.ArrayList;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.memory.InMemoryDaoImpl;
// Class
public class TestDemoService {
static ApplicationContext applicationContext = null;
static InMemoryDaoImpl userDetailsService = null;
// Initialize the application context to
// re-use in all test cases
@BeforeClass
// Method 1
public static void setup()
{
// Creating application context instance
applicationContext
= new ClassPathXmlApplicationContext(
"application-security.xml");
// Getting user details service configured in
// configuration
userDetailsService = applicationContext.getBean(
InMemoryDaoImpl.class);
}
@Test
// Method 2
// To test the valid user with valid role
public void testValidRole()
{
// Get the user by username from configured user
// details service
UserDetails userDetails
= userDetailsService.loadUserByUsername(
"geeksforgeeks");
Authentication authToken
= new UsernamePasswordAuthenticationToken(
userDetails.getUsername(),
userDetails.getPassword(),
userDetails.getAuthorities());
SecurityContextHolder.getContext()
.setAuthentication(authToken);
DemoService service
= (DemoService)applicationContext.getBean(
"demoService");
service.method();
}
// Method 3
// To test the valid user with INVALID role
@Test(expected = AccessDeniedException.class)
public void testInvalidRole()
{
UserDetails userDetails
= userDetailsService.loadUserByUsername(
"geeksforgeeks");
List<GrantedAuthority> authorities
= new ArrayList<GrantedAuthority>();
authorities.add(
new GrantedAuthorityImpl("ROLE_INVALID"));
Authentication authToken
= new UsernamePasswordAuthenticationToken(
userDetails.getUsername(),
userDetails.getPassword(), authorities);
SecurityContextHolder.getContext()
.setAuthentication(authToken);
DemoService service
= (DemoService)applicationContext.getBean(
"demoService");
service.method();
}
// Method 4
// Test the INVALID user
@Test(expected = AccessDeniedException.class)
public void testInvalidUser()
{
UserDetails userDetails
= userDetailsService.loadUserByUsername(
"geeksforgeeks2");
List<GrantedAuthority> authorities
= new ArrayList<GrantedAuthority>();
authorities.add(
new GrantedAuthorityImpl("ROLE_INVALID"));
Authentication authToken
= new UsernamePasswordAuthenticationToken(
userDetails.getUsername(),
userDetails.getPassword(), authorities);
SecurityContextHolder.getContext()
.setAuthentication(authToken);
DemoService service
= (DemoService)applicationContext.getBean(
"demoService");
service.method();
}
}
Step 6: Execute the Test Cases
Run the JUnit test class.
- Valid role test passes.
- Invalid role test fails as expected.
- Invalid user test fails as expected.
Output: Now we will see all test cases are running as depicted via the visual aid below shown as follows:

