Spring Security `permitAll()` vs. `web.ignoring()`: The Definitive Guide to Secure & Performant Applications





Spring Security: permitAll() vs web.ignoring() (Spring Boot 3) | www.codegigs.app





Spring Security: permitAll() vs web.ignoring() (Spring Boot 3)

You want to make an endpoint public. Maybe it’s your login page, maybe it’s a CSS file. You have two choices: permitAll() or web.ignoring().

They look the same. They act the same (the user sees the page). But under the hood, they are radically different.

At www.codegigs.app, I constantly see developers using web.ignoring() on their login endpoints to “fix” 403 errors. This is dangerous. It turns off all security protections—CSRF, Headers, everything.

Here is exactly when to use each, and why getting it wrong leaves you vulnerable.

The Safe Choice: permitAll()

Think of permitAll() like a security guard who checks your ID, sees you’re a guest, and waves you through. You are still “inside” the security system.

When you use permitAll(), the request still passes through the Security Filter Chain. This means:

  • CSRF protection is active (crucial for login forms).
  • Security Headers (XSS, Frame Options) are added.
  • The SecurityContext is available (so you can check if a user is logged in, even on a public page).

// SecurityConfig.java
// Spring Boot 3.2+
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
            // Use permitAll for any endpoint that has logic or forms
            .requestMatchers("/", "/login", "/register", "/api/public/**").permitAll()
            .anyRequest().authenticated()
        )
        // ... rest of config
    ;
    return http.build();
}

If you have a controller, use permitAll(). Always.

The Performance Choice: web.ignoring()

Now think of web.ignoring() like a side door that bypasses the security guard entirely. The request never enters the Spring Security filter chain.

It’s faster because it skips the filters. But it’s “unsafe” because Spring Security is completely blind to these requests. No CSRF. No Headers. No UserDetails.

Use this only for static resources (CSS, JS, Images).


// SecurityConfig.java
// Note: This returns WebSecurityCustomizer, NOT SecurityFilterChain
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
    return (web) -> web.ignoring()
        .requestMatchers("/css/**", "/js/**", "/images/**", "/favicon.ico");
}
Critical Warning: Never use web.ignoring() for your /login endpoint. If you do, you lose CSRF protection on your login form, making your users vulnerable to login-forgery attacks.

Why Does It Matter?

I debugged an app last month where the developer used web.ignoring() on a public “Contact Us” form because they were getting CSRF errors.

By ignoring the endpoint, they bypassed the CSRF check. The errors stopped. Great, right?

Wrong. They effectively turned off the firewall because the door was stuck. Any malicious site could now submit that form on behalf of a user. The correct fix was to include the CSRF token, not disable the security.

Summary: The Decision Matrix

  • Is it a static file (CSS/JS/PNG)? Use web.ignoring().
  • Is it a Controller or API endpoint? Use permitAll().
  • Is it the Login page? Use permitAll().
  • Is it H2 Console? Use web.ignoring() (usually easiest, though less secure).

Confused by the Filter Chain?

We visualize the entire request flow in our architecture module.

Stop guessing which filter runs when.

Start the Spring Security Master Class

Now that you know how to let people in, learn how to keep the wrong people out by securing your methods with annotations.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top