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

reactive-testing.mddocs/

Reactive Testing (WebTestClient)

WebTestClient integration for testing security in reactive Spring WebFlux applications, providing mutators for various authentication scenarios including OAuth2, JWT, and OIDC. This integration enables comprehensive testing of reactive security configurations and authentication flows.

Setup

WebTestClient Configuration

Configure WebTestClient with Spring Security support for reactive applications.

/**
 * Security configurers for reactive testing
 */
public class SecurityMockServerConfigurers {
    
    /**
     * Configure Spring Security with WebTestClient
     * @return MockServerConfigurer for reactive security integration
     */
    public static MockServerConfigurer springSecurity();
}

Usage Examples:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ReactiveSecurityTest {
    
    @Autowired
    private WebTestClient webTestClient;
    
    // WebTestClient is auto-configured with Spring Security in Spring Boot tests
    
    @Test
    public void testReactiveEndpoint() {
        webTestClient
            .mutateWith(mockUser())
            .get().uri("/reactive/secure")
            .exchange()
            .expectStatus().isOk();
    }
}

Authentication Mutators

Basic User Authentication

Create user-based authentication for reactive testing.

/**
 * Mock authentication with specific Authentication object
 * @param authentication The authentication to use
 * @return Mutator that applies the authentication
 */
public static <T> T mockAuthentication(Authentication authentication);

/**
 * Mock user from UserDetails
 * @param userDetails The UserDetails to use
 * @return Mutator that applies user authentication
 */
public static <T> T mockUser(UserDetails userDetails);

/**
 * Mock default user with username "user" and role "USER"
 * @return UserExchangeMutator for configuration
 */
public static UserExchangeMutator mockUser();

/**
 * Mock user with specific username
 * @param username The username for authentication
 * @return UserExchangeMutator for configuration
 */
public static UserExchangeMutator mockUser(String username);

/**
 * Fluent configuration for user authentication in reactive tests
 */
public interface UserExchangeMutator extends WebTestClientConfigurer, MockServerConfigurer {
    /** Set user password */
    UserExchangeMutator password(String password);
    
    /** Set user roles (automatically prefixed with "ROLE_") */
    UserExchangeMutator roles(String... roles);
    
    /** Set granted authorities */
    UserExchangeMutator authorities(GrantedAuthority... authorities);
}

Usage Examples:

@Test
public void testWithDefaultUser() {
    webTestClient
        .mutateWith(mockUser())  // username="user", roles=["USER"]
        .get().uri("/api/user-data")
        .exchange()
        .expectStatus().isOk();
}

@Test
public void testWithCustomUser() {
    webTestClient
        .mutateWith(mockUser("alice")
            .roles("USER", "MANAGER")
            .password("secret"))
        .get().uri("/api/manager-data")
        .exchange()
        .expectStatus().isOk();
}

@Test
public void testWithUserDetails() {
    UserDetails user = User.builder()
        .username("bob")
        .password("password")
        .authorities("ROLE_ADMIN", "READ_PRIVILEGES")
        .build();
        
    webTestClient
        .mutateWith(mockUser(user))
        .get().uri("/api/admin-data")
        .exchange()
        .expectStatus().isOk();
}

@Test
public void testWithCustomAuthentication() {
    Authentication auth = new UsernamePasswordAuthenticationToken(
        "customuser", 
        "credentials", 
        Arrays.asList(new SimpleGrantedAuthority("CUSTOM_AUTHORITY"))
    );
    
    webTestClient
        .mutateWith(mockAuthentication(auth))
        .get().uri("/api/custom")
        .exchange()
        .expectStatus().isOk();
}

JWT Authentication

Comprehensive JWT authentication support for reactive applications.

/**
 * Mock JWT authentication with default configuration
 * @return JwtMutator for configuration
 */
public static JwtMutator mockJwt();

/**
 * Fluent configuration for JWT authentication in reactive tests
 */
public interface JwtMutator extends WebTestClientConfigurer, MockServerConfigurer {
    /**
     * Configure JWT using builder consumer
     * @param jwtBuilderConsumer Consumer to configure JWT builder
     * @return JwtMutator for chaining
     */
    JwtMutator jwt(Consumer<Jwt.Builder> jwtBuilderConsumer);
    
    /**
     * Use specific JWT instance
     * @param jwt The JWT to use
     * @return JwtMutator for chaining  
     */
    JwtMutator jwt(Jwt jwt);
    
    /**
     * Set authorities for JWT authentication
     * @param authorities The granted authorities
     * @return JwtMutator for chaining
     */
    JwtMutator authorities(GrantedAuthority... authorities);
}

Usage Examples:

@Test
public void testWithJwt() {
    webTestClient
        .mutateWith(mockJwt()
            .jwt(jwt -> jwt
                .claim("sub", "user123")
                .claim("scope", "read write")
                .claim("aud", "my-app"))
            .authorities(
                new SimpleGrantedAuthority("SCOPE_read"),
                new SimpleGrantedAuthority("SCOPE_write")
            ))
        .get().uri("/api/jwt-protected")
        .exchange()
        .expectStatus().isOk();
}

@Test
public void testWithPrebuiltJwt() {
    Jwt jwt = Jwt.withTokenValue("token-value")
        .header("alg", "HS256")
        .claim("sub", "user456")
        .claim("scope", "admin")
        .build();
        
    webTestClient
        .mutateWith(mockJwt().jwt(jwt))
        .get().uri("/api/admin-jwt")
        .exchange()
        .expectStatus().isOk();
}

OAuth2 Opaque Token

Support for OAuth2 opaque token authentication in reactive applications.

/**
 * Mock OAuth2 opaque token authentication
 * @return OpaqueTokenMutator for configuration
 */
public static OpaqueTokenMutator mockOpaqueToken();

/**
 * Fluent configuration for opaque token authentication
 */
public interface OpaqueTokenMutator extends WebTestClientConfigurer, MockServerConfigurer {
    /**
     * Set token attributes
     * @param attributes Map of token attributes
     * @return OpaqueTokenMutator for chaining
     */
    OpaqueTokenMutator attributes(Map<String, Object> attributes);
    
    /**
     * Configure token attributes using consumer
     * @param attributesConsumer Consumer to configure attributes
     * @return OpaqueTokenMutator for chaining
     */
    OpaqueTokenMutator attributes(Consumer<Map<String, Object>> attributesConsumer);
    
    /**
     * Set authorities for token authentication
     * @param authorities The granted authorities
     * @return OpaqueTokenMutator for chaining
     */
    OpaqueTokenMutator authorities(GrantedAuthority... authorities);
}

Usage Examples:

@Test
public void testWithOpaqueToken() {
    webTestClient
        .mutateWith(mockOpaqueToken()
            .attributes(attrs -> {
                attrs.put("sub", "user789");
                attrs.put("scope", "read write");
                attrs.put("client_id", "my-client");
            })
            .authorities(
                new SimpleGrantedAuthority("SCOPE_read"),
                new SimpleGrantedAuthority("SCOPE_write")
            ))
        .get().uri("/api/token-secured")
        .exchange()
        .expectStatus().isOk();
}

OAuth2 Login

OAuth2 login authentication support for reactive applications.

/**
 * Mock OAuth2 login authentication
 * @return OAuth2LoginMutator for configuration
 */
public static OAuth2LoginMutator mockOAuth2Login();

/**
 * Fluent configuration for OAuth2 login authentication
 */
public interface OAuth2LoginMutator extends WebTestClientConfigurer, MockServerConfigurer {
    /**
     * Set OAuth2 user attributes
     * @param attributes Map of user attributes
     * @return OAuth2LoginMutator for chaining
     */
    OAuth2LoginMutator attributes(Map<String, Object> attributes);
    
    /**
     * Configure OAuth2 user attributes using consumer
     * @param attributesConsumer Consumer to configure attributes
     * @return OAuth2LoginMutator for chaining
     */
    OAuth2LoginMutator attributes(Consumer<Map<String, Object>> attributesConsumer);
    
    /**
     * Set client registration ID
     * @param clientRegistrationId The client registration ID
     * @return OAuth2LoginMutator for chaining
     */
    OAuth2LoginMutator clientRegistrationId(String clientRegistrationId);
    
    /**
     * Set authorities for OAuth2 authentication
     * @param authorities The granted authorities
     * @return OAuth2LoginMutator for chaining
     */
    OAuth2LoginMutator authorities(GrantedAuthority... authorities);
}

Usage Examples:

@Test
public void testWithOAuth2Login() {
    webTestClient
        .mutateWith(mockOAuth2Login()
            .clientRegistrationId("google")
            .attributes(attrs -> {
                attrs.put("sub", "12345");
                attrs.put("name", "John Doe");
                attrs.put("email", "john@example.com");
            })
            .authorities(new SimpleGrantedAuthority("ROLE_USER")))
        .get().uri("/oauth2/user")
        .exchange()
        .expectStatus().isOk();
}

OIDC Login

OpenID Connect login authentication support for reactive applications.

/**
 * Mock OIDC login authentication
 * @return OidcLoginMutator for configuration
 */
public static OidcLoginMutator mockOidcLogin();

/**
 * Fluent configuration for OIDC login authentication
 */
public interface OidcLoginMutator extends WebTestClientConfigurer, MockServerConfigurer {
    /**
     * Configure ID token
     * @param idTokenBuilderConsumer Consumer to configure ID token
     * @return OidcLoginMutator for chaining
     */
    OidcLoginMutator idToken(Consumer<OidcIdToken.Builder> idTokenBuilderConsumer);
    
    /**
     * Configure user info
     * @param userInfoConsumer Consumer to configure user info
     * @return OidcLoginMutator for chaining
     */
    OidcLoginMutator userInfo(Consumer<Map<String, Object>> userInfoConsumer);
    
    /**
     * Set client registration ID
     * @param clientRegistrationId The client registration ID
     * @return OidcLoginMutator for chaining
     */
    OidcLoginMutator clientRegistrationId(String clientRegistrationId);
    
    /**
     * Set authorities for OIDC authentication
     * @param authorities The granted authorities
     * @return OidcLoginMutator for chaining
     */
    OidcLoginMutator authorities(GrantedAuthority... authorities);
}

Usage Examples:

@Test
public void testWithOidcLogin() {
    webTestClient
        .mutateWith(mockOidcLogin()
            .clientRegistrationId("auth0")
            .idToken(token -> token
                .claim("sub", "user123")
                .claim("email", "user@example.com")
                .claim("email_verified", true))
            .userInfo(userInfo -> {
                userInfo.put("given_name", "John");
                userInfo.put("family_name", "Doe");
                userInfo.put("picture", "https://example.com/avatar.jpg");
            })
            .authorities(
                new SimpleGrantedAuthority("ROLE_USER"),
                new SimpleGrantedAuthority("SCOPE_openid")
            ))
        .get().uri("/oidc/userinfo")
        .exchange()
        .expectStatus().isOk();
}

OAuth2 Client

OAuth2 client configuration for reactive applications.

/**
 * Mock OAuth2 client with default configuration
 * @return OAuth2ClientMutator for configuration
 */
public static OAuth2ClientMutator mockOAuth2Client();

/**
 * Mock OAuth2 client with specific registration ID
 * @param registrationId The client registration ID
 * @return OAuth2ClientMutator for configuration
 */
public static OAuth2ClientMutator mockOAuth2Client(String registrationId);

/**
 * Fluent configuration for OAuth2 client
 */
public interface OAuth2ClientMutator extends WebTestClientConfigurer, MockServerConfigurer {
    /**
     * Set client registration ID
     * @param registrationId The client registration ID
     * @return OAuth2ClientMutator for chaining
     */
    OAuth2ClientMutator registrationId(String registrationId);
    
    /**
     * Set access token
     * @param accessToken The access token
     * @return OAuth2ClientMutator for chaining
     */
    OAuth2ClientMutator accessToken(OAuth2AccessToken accessToken);
    
    /**
     * Configure access token using consumer
     * @param accessTokenConsumer Consumer to configure access token
     * @return OAuth2ClientMutator for chaining
     */
    OAuth2ClientMutator accessToken(Consumer<OAuth2AccessToken.Builder> accessTokenConsumer);
}

Usage Examples:

@Test
public void testWithOAuth2Client() {
    webTestClient
        .mutateWith(mockOAuth2Client("api-client")
            .accessToken(token -> token
                .tokenType(OAuth2AccessToken.TokenType.BEARER)
                .scopes(Set.of("read", "write"))
                .tokenValue("access-token-value")))
        .get().uri("/api/client-data")
        .exchange()
        .expectStatus().isOk();
}

CSRF Protection

CSRF token support for reactive applications.

/**
 * Mock CSRF support for reactive applications
 * @return CsrfMutator for configuration
 */
public static CsrfMutator csrf();

/**
 * Fluent configuration for CSRF in reactive tests
 */
public interface CsrfMutator extends WebTestClientConfigurer, MockServerConfigurer {
    // CSRF-specific configuration methods for reactive testing
}

Usage Examples:

@Test
public void testCsrfProtectedEndpoint() {
    webTestClient
        .mutateWith(csrf())
        .mutateWith(mockUser())
        .post().uri("/api/form-submit")
        .bodyValue("data=test")
        .exchange()
        .expectStatus().isOk();
}

Common Reactive Testing Patterns

Comprehensive Reactive Security Test

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ReactiveSecurityIntegrationTest {
    
    @Autowired
    private WebTestClient webTestClient;
    
    @Test
    public void testUnauthenticatedAccess() {
        webTestClient
            .get().uri("/api/public")
            .exchange()
            .expectStatus().isOk();
            
        webTestClient
            .get().uri("/api/secure")
            .exchange()
            .expectStatus().isUnauthorized();
    }
    
    @Test
    public void testUserAuthentication() {
        webTestClient
            .mutateWith(mockUser("testuser").roles("USER"))
            .get().uri("/api/user-data")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class)
            .value(response -> {
                assertThat(response).contains("testuser");
            });
    }
    
    @Test
    public void testAdminOnlyEndpoint() {
        // Test user access - should be forbidden
        webTestClient
            .mutateWith(mockUser("user").roles("USER"))
            .get().uri("/api/admin")
            .exchange()
            .expectStatus().isForbidden();
            
        // Test admin access - should succeed
        webTestClient
            .mutateWith(mockUser("admin").roles("ADMIN"))
            .get().uri("/api/admin")
            .exchange()
            .expectStatus().isOk();
    }
    
    @Test
    public void testJwtAuthentication() {
        webTestClient
            .mutateWith(mockJwt()
                .jwt(jwt -> jwt
                    .claim("sub", "jwt-user")
                    .claim("scope", "read write"))
                .authorities(
                    new SimpleGrantedAuthority("SCOPE_read"),
                    new SimpleGrantedAuthority("SCOPE_write")
                ))
            .get().uri("/api/jwt-data")
            .exchange()
            .expectStatus().isOk();
    }
    
    @Test
    public void testOAuth2Login() {
        webTestClient
            .mutateWith(mockOAuth2Login()
                .attributes(attrs -> {
                    attrs.put("sub", "oauth-user");
                    attrs.put("name", "OAuth User");
                    attrs.put("email", "oauth@example.com");
                }))
            .get().uri("/oauth2/profile")
            .exchange()
            .expectStatus().isOk()
            .expectBody()
            .jsonPath("$.name").isEqualTo("OAuth User")
            .jsonPath("$.email").isEqualTo("oauth@example.com");
    }
    
    @Test
    public void testReactiveCsrfProtection() {
        webTestClient
            .mutateWith(csrf())
            .mutateWith(mockUser())
            .post().uri("/api/form")
            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .bodyValue("field=value")
            .exchange()
            .expectStatus().isOk();
    }
}

Testing Reactive Security Configurations

@Test
public void testSecurityConfiguration() {
    // Test method security
    webTestClient
        .mutateWith(mockUser("user").roles("USER"))
        .get().uri("/api/user-method")
        .exchange()
        .expectStatus().isOk();
        
    webTestClient
        .mutateWith(mockUser("user").roles("USER"))  
        .get().uri("/api/admin-method")
        .exchange()
        .expectStatus().isForbidden();
        
    // Test reactive security context
    webTestClient
        .mutateWith(mockUser("testuser"))
        .get().uri("/api/current-user")
        .exchange()
        .expectStatus().isOk()
        .expectBody(String.class)
        .isEqualTo("testuser");
}

Testing Error Scenarios

@Test  
public void testAuthenticationFailures() {
    // Test expired JWT
    Jwt expiredJwt = Jwt.withTokenValue("expired-token")
        .header("alg", "HS256")
        .claim("sub", "user")
        .claim("exp", Instant.now().minusSeconds(3600))  // Expired
        .build();
        
    webTestClient
        .mutateWith(mockJwt().jwt(expiredJwt))
        .get().uri("/api/secure")
        .exchange()
        .expectStatus().isUnauthorized();
        
    // Test insufficient authorities
    webTestClient
        .mutateWith(mockUser("user").roles("USER"))
        .get().uri("/api/admin-only")
        .exchange()
        .expectStatus().isForbidden();
}

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