CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-security--spring-security-test

Spring Security Test provides comprehensive testing utilities for Spring Security applications with mock authentication, security context testing, and web security testing features.

Pending
Overview
Eval results
Files

security-context-annotations.mddocs/

Security Context Annotations

Core testing annotations for declarative security context management, providing method and class-level authentication setup without complex configuration. These annotations integrate with Spring Test's TestExecutionListener framework to automatically establish security contexts before test execution.

Capabilities

@WithMockUser

Creates a mock authenticated user with customizable username, password, roles, and authorities.

/**
 * Creates a mock authenticated user for testing
 * Can be applied to test methods or test classes
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory = WithMockUserSecurityContextFactory.class)
public @interface WithMockUser {
    /** Username for the mock user (default: "user") */
    String value() default "user";
    
    /** Username for the mock user (takes precedence over value()) */
    String username() default "";
    
    /** Password for the mock user (default: "password") */
    String password() default "password";
    
    /** User roles, automatically prefixed with "ROLE_" (default: {"USER"}) */
    String[] roles() default {"USER"};
    
    /** Granted authorities, not automatically prefixed */
    String[] authorities() default {};
    
    /** When to establish the security context */
    TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD;
}

Usage Examples:

// Method-level with default user
@Test
@WithMockUser
public void testWithDefaultUser() {
    // Test runs with username="user", roles={"USER"}
}

// Custom username and roles
@Test
@WithMockUser(username = "admin", roles = {"ADMIN", "USER"})
public void testWithAdmin() {
    // Test runs with admin privileges
}

// Using authorities instead of roles
@Test
@WithMockUser(authorities = {"READ_PRIVILEGES", "WRITE_PRIVILEGES"})
public void testWithCustomAuthorities() {
    // Test runs with specific authorities (no ROLE_ prefix)
}

// Class-level annotation applies to all methods
@WithMockUser(roles = "MANAGER")
public class ManagerTests {
    @Test
    public void testManagerFeature() {
        // Inherits manager role from class annotation
    }
    
    @Test
    @WithAnonymousUser  // Override class-level annotation
    public void testAnonymousAccess() {
        // Runs as anonymous user
    }
}

@WithAnonymousUser

Creates an anonymous authentication for testing scenarios where no authentication is present.

/**
 * Creates anonymous authentication for testing
 * Can be applied to test methods or test classes
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory = WithAnonymousUserSecurityContextFactory.class)
public @interface WithAnonymousUser {
    /** When to establish the security context */
    TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD;
}

Usage Examples:

@Test
@WithAnonymousUser
public void testAnonymousAccess() {
    // Test runs with anonymous authentication
    // Useful for testing public endpoints or access denied scenarios
}

// Override class-level security annotation
@WithMockUser(roles = "USER")
public class UserTests {
    @Test
    @WithAnonymousUser
    public void testPublicEndpoint() {
        // Overrides class-level @WithMockUser
    }
}

@WithUserDetails

Loads a user via UserDetailsService for more realistic testing scenarios using actual user data.

/**
 * Loads user via UserDetailsService for testing
 * Requires a UserDetailsService bean in the test context
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory = WithUserDetailsSecurityContextFactory.class)
public @interface WithUserDetails {
    /** Username to lookup via UserDetailsService (default: "user") */
    String value() default "user";
    
    /** Specific UserDetailsService bean name to use */
    String userDetailsServiceBeanName() default "";
    
    /** When to establish the security context */
    TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD;
}

Usage Examples:

@Test
@WithUserDetails("john.doe@example.com")
public void testWithRealUser() {
    // Loads user "john.doe@example.com" via UserDetailsService
    // Uses actual user data including roles and authorities
}

@Test
@WithUserDetails(value = "admin", userDetailsServiceBeanName = "customUserDetailsService")
public void testWithCustomService() {
    // Uses specific UserDetailsService bean
}

@SecurityTestExecutionListeners

Meta-annotation that enables only Spring Security test execution listeners, useful when testing security features without a full application context.

/**
 * Meta-annotation that enables Spring Security TestExecutionListeners
 * Use when testing security without full Spring context setup
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@TestExecutionListeners(
    inheritListeners = false,
    listeners = {
        WithSecurityContextTestExecutionListener.class,
        ReactorContextTestExecutionListener.class
    }
)
public @interface SecurityTestExecutionListeners {
}

Usage Examples:

// Use when you only need security testing without full Spring Boot context
@SecurityTestExecutionListeners
public class SecurityUnitTests {
    
    @Test
    @WithMockUser(roles = "USER")
    public void testSecurityLogic() {
        // Test security-related logic without full application context
        // Only security test execution listeners are enabled
    }
}

// Useful for lightweight security testing
@SecurityTestExecutionListeners
public class AuthenticationUnitTests {
    
    @Test
    @WithUserDetails("testuser")
    public void testUserDetailsLogic() {
        // Tests user details without loading full Spring context
        // Performance benefits for focused security tests
    }
}

@WithSecurityContext

Meta-annotation for creating custom security context annotations with custom factory implementations.

/**
 * Meta-annotation for creating custom security context annotations
 * Requires a factory implementation
 */
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface WithSecurityContext {
    /** Factory class that creates the SecurityContext */
    Class<? extends WithSecurityContextFactory<? extends Annotation>> factory();
    
    /** When to establish the security context */
    TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD;
}

Usage Examples:

// Custom annotation definition
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithCustomUserSecurityContextFactory.class)
public @interface WithCustomUser {
    String username() default "customUser";
    String department() default "IT";
}

// Custom factory implementation
public class WithCustomUserSecurityContextFactory 
    implements WithSecurityContextFactory<WithCustomUser> {
    
    @Override
    public SecurityContext createSecurityContext(WithCustomUser annotation) {
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        
        // Create custom authentication with department-specific authorities
        List<GrantedAuthority> authorities = Arrays.asList(
            new SimpleGrantedAuthority("ROLE_USER"),
            new SimpleGrantedAuthority("DEPT_" + annotation.department().toUpperCase())
        );
        
        UsernamePasswordAuthenticationToken auth = 
            new UsernamePasswordAuthenticationToken(
                annotation.username(), 
                "password", 
                authorities
            );
        
        context.setAuthentication(auth);
        return context;
    }
}

// Usage of custom annotation
@Test
@WithCustomUser(username = "alice", department = "FINANCE")
public void testCustomUser() {
    // Test runs with custom user having ROLE_USER and DEPT_FINANCE authorities
}

Supporting Classes

WithSecurityContextFactory Interface

Factory interface for creating security contexts from annotations.

/**
 * Factory interface for creating SecurityContext from annotation
 * @param <A> The annotation type this factory handles
 */
public interface WithSecurityContextFactory<A extends Annotation> {
    /**
     * Create SecurityContext from the provided annotation
     * @param annotation The annotation instance with configuration
     * @return SecurityContext to be used for the test
     */
    SecurityContext createSecurityContext(A annotation);
}

Built-in Factory Implementations

// Factory for @WithMockUser
public class WithMockUserSecurityContextFactory 
    implements WithSecurityContextFactory<WithMockUser> {
    public SecurityContext createSecurityContext(WithMockUser withUser);
}

// Factory for @WithAnonymousUser  
public class WithAnonymousUserSecurityContextFactory 
    implements WithSecurityContextFactory<WithAnonymousUser> {
    public SecurityContext createSecurityContext(WithAnonymousUser withAnonymousUser);
}

// Factory for @WithUserDetails
public class WithUserDetailsSecurityContextFactory 
    implements WithSecurityContextFactory<WithUserDetails> {
    public SecurityContext createSecurityContext(WithUserDetails withUserDetails);
}

TestExecutionEvent Enum

Defines when the security context should be established during test execution.

/**
 * Defines when SecurityContext should be established
 */
public enum TestExecutionEvent {
    /** Before test method execution (default) */
    TEST_METHOD,
    
    /** Before test execution, after setup methods */
    TEST_EXECUTION
}

Integration with Spring Test

WithSecurityContextTestExecutionListener

The test execution listener that processes security context annotations.

/**
 * TestExecutionListener that processes @WithSecurityContext annotations
 * Order: 10000 (runs after most other listeners)
 */
public class WithSecurityContextTestExecutionListener implements TestExecutionListener {
    // Processes annotations before test method/execution
    // Clears security context after test completion
}

Annotation Processing Order

  1. Class-level annotations are processed first
  2. Method-level annotations override class-level settings
  3. Security context is established based on setupBefore value
  4. Test execution proceeds with established context
  5. Context cleanup occurs after test completion

Common Patterns

Method Override Pattern

@WithMockUser(roles = "USER")  // Class-level default
public class SecurityTests {
    
    @Test
    public void testUserFeature() {
        // Uses class-level USER role
    }
    
    @Test
    @WithMockUser(roles = "ADMIN")  // Override for this method
    public void testAdminFeature() {
        // Uses ADMIN role
    }
    
    @Test
    @WithAnonymousUser  // Override to anonymous
    public void testPublicAccess() {
        // No authentication
    }
}

Parameterized Tests

@ParameterizedTest
@ValueSource(strings = {"user1", "user2", "admin"})
@WithUserDetails  // Uses parameter value as username
public void testMultipleUsers(String username) {
    // Test runs for each username via UserDetailsService
}

Nested Test Classes

@WithMockUser(roles = "USER")
public class SecurityNestedTests {
    
    @Nested
    @WithMockUser(roles = "ADMIN")  // Overrides parent class annotation
    class AdminTests {
        @Test
        public void testAdminFeature() {
            // Runs with ADMIN role
        }
    }
    
    @Nested
    class UserTests {
        @Test
        public void testUserFeature() {
            // Inherits USER role from parent class
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework-security--spring-security-test

docs

index.md

mockmvc-integration.md

reactive-testing.md

security-context-annotations.md

test-context-management.md

tile.json