Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Security filter chain: authentication, CSRF and request order

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A SecurityFilterChain applies selected security filters to an HTTP request before the request reaches the controller.

Download Spring source kit

This lesson uses the downloadable source kit: Java 21, Spring Boot 4.0.8 and its managed Spring Framework 7 dependencies. The version is pinned for repeatable builds.

Specify public and protected paths

The receipt application allows anonymous health checks and requires authentication for other requests. A real GET without credentials returns 401; the same API GET with the fixture Basic credentials succeeds. Those tests prove request behavior, not merely that a SecurityFilterChain bean exists.

The user store and password are local learning fixtures. They are not a deployable account system. Basic credentials need TLS outside loopback, and production identity storage, rotation, authorization roles and tenant ownership must be designed separately.

Do not disable a protection to fix a test

CSRF remains enabled. A POST carrying a Basic header but no token is rejected before Basic authentication completes in this fixture, returning 401. A request with an already-established test user but no CSRF token returns 403. With the established user and a valid token, the controller accepts a valid command.

That distinction is why tests check filter behavior instead of assuming every rejected authenticated-looking request returns the same status. Cookie or browser-managed credentials make CSRF relevant; moving to a bearer API requires a deliberate credential and browser threat model.

Checked source

Java
package in.aitrove.learning;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.config.Customizer;
@Configuration(proxyBeanMethods=false)
public class ReceiptSecurity {
    @Bean PasswordEncoder passwordEncoder() { return PasswordEncoderFactories.createDelegatingPasswordEncoder(); }
    @Bean InMemoryUserDetailsManager readers(PasswordEncoder encoder) {
        // Local source-kit credential only; never deploy this user store.
        return new InMemoryUserDetailsManager(User.withUsername("local-reader")
            .password(encoder.encode("local-fixture-only")).roles("READER").build());
    }
    @Bean SecurityFilterChain receiptChain(HttpSecurity http) throws Exception {
        http.cors(Customizer.withDefaults()).authorizeHttpRequests(requests -> requests
            .requestMatchers("/actuator/health").permitAll().anyRequest().authenticated())
            .httpBasic(Customizer.withDefaults());
        return http.build(); // CSRF stays enabled for this session-capable learning application.
    }
}

Test the boundary

Run mvn test in the source-kit directory. HttpSecurityBoundaryTest checks the behavior described here. Java excerpts belong to the named source-kit classes; they are not independent source files unless the complete class is shown.

Costs and boundaries

Password verification can dominate authentication cost. Filter order also affects which work runs before rejection. The fixture does not measure capacity or provide production rate limiting.

Common Mistakes

  • Never deploy the fixture account as a production user store.
  • Do not disable CSRF merely to make POST tests pass.
  • CORS does not replace authentication or authorization.

Read next

Password encoding, Spring MVC CORS: a browser-origin policy is not authentication, Mockmvc tests.

Extend this boundary

Continue with Spring method authorization: test the proxied service boundary.

Extend the tested workflow

Continue with Spring Security JWT resource server: validate trust before checking scope.

Continue with checked upload and readiness

Continue with Spring Security health probes: expose only the health path.

spring
spring-boot
security-filter-chain
Storage details