Spring Security 6.x drops the old WebSecurityConfigurerAdapter. You must use SecurityFilterChain beans now.
The AuthenticationProvider chain order matters. First match wins. A misordered chain silently breaks OAuth2 login.
@EnableMethodSecurity replaces @EnableGlobalMethodSecurity. Mixing them corrupts method-level checks.
CSRF is enabled by default in Spring Security 6.x. Your REST API won't accept POST without proper configuration.
JWT validation failures from Resource Server 6.x don't throw exceptions. They return 401 with a generic error.
✦ Definition~90s read
What is Spring Security Interview Questions?
Spring Security is the de facto security framework for Java applications. In Spring Boot 3.x, it's been overhauled. The old classes are deprecated. The new component-based model uses SecurityFilterChain beans. Authentication happens through a chain of AuthenticationProvider instances.
★
Spring Security is like a bouncer at a club.
Authorization is handled via method security annotations or request matchers. It's not a library. It's a collection of filters that modify the request and response objects. Each filter has a single responsibility. Authentication filters, exception translation filters, authorization filters.
They chain together. One breaks the chain, the whole thing fails silently. The biggest shift in 6.x is the removal of the old configuration adapter. You now declare beans. The framework wires them. This is better. It gives you more control. But it also introduces new failure modes.
Especially around filter ordering.
Plain-English First
Spring Security is like a bouncer at a club. It checks IDs (authentication), decides which rooms you can enter (authorization), and makes sure nobody sneaks in through the fire exit (CSRF protection). When the bouncer gets the wrong list or checks IDs in the wrong order, people end up in the VIP section who shouldn't be there.
The PagerDuty alert went off at 2:47 AM. Our payment gateway was returning 401s. All users. Not just some. Everyone. The on-call engineer checked the logs. 'Access Denied' messages from Spring Security. No stack trace, just a generic error. The immediate assumption was a token issue. Maybe the JWT signing key rotated? Maybe the OAuth2 provider was down? We checked all that. Keys were valid. Provider was healthy. The issue was deeper. It was a security filter ordering bug. The AuthenticationProvider chain was out of order. The default password-based provider was catching requests meant for the OAuth2 provider. Every single API call was being checked against the wrong authentication method. We spent forty-five minutes debugging something that should have been caught in code review. The fix? Reordering three beans in the SecurityFilterChain configuration. That's it. Three lines of code. But those three lines cost the company about fifteen thousand dollars in lost transaction revenue. I've seen this pattern repeat across three different production systems in the last year. Spring Security 6.x broke the old assumptions. Devs still write configuration like it's 2019. They get burned. This article covers exactly what breaks, how to debug it, and what the interviewers are asking about it now.
SecurityFilterChain: The Only Way to Configure Now
Spring Security 6.x deleted the old WebSecurityConfigurerAdapter. I've seen teams upgrade dependencies and expect things to keep working. They don't. The application starts but security is completely broken. You get full access to everything. Or you get locked out of everything. There's no graceful degradation. You must define a SecurityFilterChain @Bean. This bean replaces the old configure(HttpSecurity) method. The new approach is simpler but unforgiving. You build a filter chain declaratively. Each filter gets added in order. A common mistake: defining multiple SecurityFilterChain beans without ordering them correctly. Spring picks one arbitrarily if you don't use @Order. This causes random 401s that appear and disappear with each restart. I fixed a production bug where a second SecurityFilterChain bean was intercepting all requests before the first one. The team added an actuator-specific chain but forgot the @Order annotation. The actuator chain ran first and rejected everything. Always annotate your SecurityFilterChain beans with @Order, starting from the most specific path to the least specific.
⚠ Production Trap:
Forgetting @Order causes non-deterministic filter chain selection. You get 401s that come and go. This is a hard-to-reproduce bug that wastes hours.
📊 Production Insight
In production, always define one SecurityFilterChain per path pattern. Never rely on a single catch-all chain for a complex app.
🎯 Key Takeaway
SecurityFilterChain beans must have explicit @Order. Most specific routes first. Least specific last.
thecodeforge.io
Spring Security Interview Questions
AuthenticationProvider Chain: The Hidden Source of 401s
The AuthenticationProvider chain is a list. Spring Security iterates through it. The first provider to return a non-null Authentication wins. This is the core of authentication. If you have multiple providers — like a password provider and an OAuth2 provider — their order decides which one runs. Put the wrong one first and the second never fires. A team I worked with added LDAP authentication as a fallback. They put the LDAP provider before the OAuth2 provider. Every JWT request was being sent to LDAP. LDAP rejected it. The chain stopped. The user got a 401. The fix was trivial: swap the provider order. But finding it required adding debug logging to ProviderManager. The AuthenticationProvider interface is simple. Implement supports() and authenticate(). But the chain management is invisible. Never assume the order matches your bean declaration order in the SecurityFilterChain builder. Spring Security collects all AuthenticationProvider beans from the application context. The order depends on bean discovery order, which is not guaranteed. Use the @Order annotation on each provider, or explicitly set the provider list in the AuthenticationManagerBuilder.
💡Senior Shortcut:
Log the provider chain at startup with a simple @PostConstruct in a configuration class. Call ProviderManager.getProviders() if accessible, or inject AuthenticationManager and log its class name.
📊 Production Insight
The provider chain is a list. First match wins. Treat it like a chain of responsibility with no fallback.
🎯 Key Takeaway
AuthenticationProvider ordering is critical. Always order most specific (like JWT) before generic (like password). Log the chain on startup.
Method Security in 6.x: @EnableMethodSecurity Is Not Optional
Old code uses @EnableGlobalMethodSecurity. It still compiles in Spring Boot 3.x. But it doesn't wire into the new security infrastructure. Your @PreAuthorize annotations become decorative. They compile, they exist in bytecode, but the AOP interceptor never runs. I saw this at a fintech startup. They migrated to Spring Boot 3.2 but kept the old annotation. All their role checks were silently ignored. Any user could call any admin endpoint. The fix required removing the old dependency entirely. The new annotation is @EnableMethodSecurity. It's simpler. You pass a single attribute for pre/post, secured, jsr250. But the real change is internals. The old approach used a Proxy around the bean. The new one uses a MethodSecurityInterceptor that hooks into Spring's AOP infrastructure. It's more composable. But it's also easier to break. If you have a custom PermissionEvaluator, register it as a bean. Don't manually wire it. The new method security infrastructure auto-detects beans of type PermissionEvaluator. Manual wiring causes double invocation or no invocation. We debugged this by checking the method security interceptor count. Two interceptors for the same method meant a configuration conflict.
⚠ Never Do This:
Do not mix @EnableGlobalMethodSecurity with @EnableMethodSecurity. The old annotation creates a separate interceptor chain that conflicts with the new one. Pick one. The new one.
📊 Production Insight
If @PreAuthorize seems to not fire, check which @Enable annotation you imported. This is the single most common upgrade bug.
🎯 Key Takeaway
@EnableMethodSecurity replaces @EnableGlobalMethodSecurity. Mixing them breaks method security silently. Remove the old annotation entirely.
thecodeforge.io
Spring Security Interview Questions
CORS and CSRF: The Stateless API Configuration Trap
Spring Security 6.x enables CSRF by default. For session-based web apps, this is correct. For stateless REST APIs, it kills your POST requests. Every POST, PUT, DELETE, PATCH returns a 403. The error message says 'Invalid CSRF token'. You add the disable line and it works. The trap? You forget that CORS and CSRF interact. CORS handles browser preflight requests. CSRF handles state-changing requests. They are separate filters. I've seen teams disable CSRF but forget CORS. Then their frontend gets CORS errors on OPTIONS preflight. The fix is two separate configurations. First CORS, then CSRF. Also, if you use OAuth2 with a Bearer token, you don't need CSRF. The token provides origin validation. Disabling CSRF for OAuth2 APIs is best practice. The code is simple but forgetting it is expensive. At my last company, a junior dev spent two days debugging a 403 on a POST endpoint. He forgot CSRF disable. The fix took five seconds.
🔥Interview Gold:
Interviewers ask: 'When should you disable CSRF?' Answer: When your API is stateless and uses token-based authentication. If the server doesn't set a session cookie, CSRF is irrelevant.
📊 Production Insight
CORS and CSRF are separate filters that both affect POST requests. Debug CORS first (preflight), then CSRF (actual request).
🎯 Key Takeaway
For stateless REST APIs in Spring Security 6.x, always disable CSRF and configure CORS explicitly. They are separate concerns.
OAuth2 Resource Server: JWT Validation That Fails Silently
Spring Security's OAuth2 resource server support is solid. But the error handling is poor. When a JWT fails validation — expired, wrong issuer, bad signature — you get a generic 401. No details in the response. The real error is hidden in TRACE level logs. This is a security feature, they say. It prevents information leakage. But in production, it's a debugging nightmare. I spent three hours once chasing a 401 that was caused by a clock skew issue on the authorization server. The JWT was technically valid but the server's clock was five minutes ahead. Spring Security's default clock skew tolerance is 60 seconds. Five minutes exceeded it. The fix was to configure the NimbusJwtDecoder with a custom ClockSkew. But first I had to find the real error. Enable TRACE logging for org.springframework.security.oauth2. Then you see 'JWT validation failed: Token expired at ...'. Always enable this logging in staging environments. Never in production unless debugging. Also, the JwtDecoder bean must be present. If it's missing, Spring Security falls back to opaque token introspection. If your authorization server doesn't support introspection, you get a 401 too. The JwtDecoder bean is auto-configured if you have the right dependency. Missing the spring-security-oauth2-jose dependency is another common cause.
⚠ Production Trap:
Clock skew on the authorization server causes silent 401s. The error says 'expired' but the token is valid. Always configure a clock skew tolerance in JwtDecoder.
📊 Production Insight
Error responses from OAuth2 resource server are deliberately vague. Always keep TRACE logging enabled in dev/staging to see the real error message.
🎯 Key Takeaway
JWT validation failures in Spring Security 6.x are silent. Enable OAuth2 TRACE logging. Configure clock skew tolerance. Verify JwtDecoder bean exists.
Testing Security Config: The Component Scan Ordering Bug
Security tests in Spring Boot 3.x need @WebMvcTest or @SpringBootTest with auto-configured security. But a common bug: your test's SecurityFilterChain overrides the production one incorrectly. Component scanning order causes tests to pick up wrong beans. I fixed a bug where a test had a @TestConfiguration that defined a custom SecurityFilterChain with no authorization. Every request was permitted. The test passed. But the same code in production returned 401s. The fix was to use @SpringBootTest with a specific profile, not @TestConfiguration. @TestConfiguration beans override the main context. If your test configuration defines a SecurityFilterChain, it replaces the production one. Use @ActiveProfiles("test") and have a separate application-test.yml with permissive security. Never define SecurityFilterChain beans in test configurations. Another trick: use @AutoConfigureMockMvc with @WithMockUser annotations. They simulate authentication without needing a real provider. This isolates the test from the provider chain. We saw tests that relied on the real OAuth2 provider in CI. The CI environment didn't have network access to the authorization server. Tests failed. We switched to @WithMockUser and the problem disappeared.
💡Senior Shortcut:
Use @WithMockUser instead of real authentication in unit tests. It decouples the test from the provider chain and network dependencies.
📊 Production Insight
Test SecurityFilterChain beans override production ones. Use profiles, not @TestConfiguration, to avoid this trap.
🎯 Key Takeaway
Never define SecurityFilterChain in @TestConfiguration. Use @ActiveProfiles("test") and per-profile security config instead.
The AuthenticationManager Pipeline: Why Your Custom Provider Vanishes
AuthenticationManager is the coordinator, not the bouncer. It receives an authentication request and delegates to a list of AuthenticationProviders. The first provider that says "yes" wins. The failure point? You register a custom provider but it lives at the bottom of the chain — Spring Security's built-in DaoAuthenticationProvider or OAuth2 provider runs first and returns a partial success, short-circuiting yours.
The fix is simple: order your providers. Use the @Order annotation or inject them into a ProviderManager bean in the correct sequence, lowest order number first. If you need your custom provider to always check before the default, give it @Order(0). For security-critical flows, attach an AuthenticationEventPublisher and log each AuthenticationSuccessEvent - you'll see immediately which provider is actually granting access.
The real issue here is that most devs think AuthenticationManager is magic. It's not. It's a do-while loop with a bad error message.
2025-01-15 10:32:01.456 DEBUG [http-nio-8080-exec-3] o.s.s.a.ProviderManager: Authentication attempt using CustomAuthenticationProvider
⚠ Production Trap:
If you don't explicitly construct the ProviderManager, Spring Boot auto-wires ALL providers in an unpredictable order. I've seen TicketGrantingToken providers fail silently for six months before a code review caught the ordering bug.
🎯 Key Takeaway
AuthenticationProvider ordering is deterministic — break the silence by explicitly constructing ProviderManager with your custom provider first.
FilterOrdering: The Invisible Bug That Kills Your Custom Filters
Every filter in Spring Security is registered on a security filter chain with a position — BEFORE, AFTER, or REPLACE a known filter. The hidden failure is that addFilterBefore(myFilter, UsernamePasswordAuthenticationFilter.class) does what you said: it places your filter right before username/password processing. But if you misidentified the target filter (like using BasicAuthenticationFilter instead of UsernamePasswordAuthenticationFilter for a form-login app), your filter runs in the wrong phase.
The consequence? Request headers are parsed too early or too late. The request body is already consumed. The security context doesn't yet exist. You silently swallow an entire auth flow because your filter reads an Authorization header before the CORS filter strips it.
Use @Order on FilterRegistrationBean to control servlet container filter ordering separately from the security filter chain. For custom security filters, always reference the exact filter you want to anchor against. When debugging, enable TRACE logging on org.springframework.security.web.FilterChainProxy — it prints the entire filter chain order on startup. Memorize that output.
If you see your filter in the log but it still doesn't execute, you have a path mismatch. The security filter chain only runs for paths matched by requestMatchers() in your SecurityFilterChain bean.
Run curl -v -X OPTIONS /api/your-endpoint — if you get a 401 instead of a 403, your custom filter is running before CORS headers are set. Move it after CorsFilter.
🎯 Key Takeaway
Filter order is explicit — always anchor your custom filter to a KNOWN filter position, and use TRACE logging to verify the chain.
● Production incidentPOST-MORTEMseverity: high
The AuthenticationProvider That Ate Our OAuth2 Login
Symptom
All authenticated endpoints returned 401 Access Denied. OAuth2 login flows completed successfully but subsequent API calls failed. No unusual log errors — just generic security warnings.
Assumption
The team thought the JWT signing key had rotated or the OAuth2 provider's public certificate was expired. They regenerated keys. No effect.
Root cause
The SecurityFilterChain configuration had the DaoAuthenticationProvider listed before the OAuth2AuthenticationProvider. Every request was being authenticated against the password-based provider first, which rejected all JWT tokens. Spring Security's provider chain stops at the first successful authentication. The OAuth2 provider never got a chance.
Fix
Reordered the AuthenticationProvider beans in the SecurityFilterChain configuration. Moved the OAuth2AuthenticationProvider declaration before the DaoAuthenticationProvider. Added @Order annotations to ensure consistent ordering across deployments. Also added a logging filter that prints the provider chain on startup.
Key lesson
AuthenticationProvider ordering is deterministic but invisible.
Always log the resolved provider chain during initialization.
Never assume the default ordering matches your intent.
Production debug guideSymptom → root cause → fix for the failures that actually happen4 entries
Symptom · 01
401 Unauthorized on all authenticated endpoints after OAuth2 login
→
Fix
Check the AuthenticationProvider chain. Add a breakpoint or log statement in AbstractAuthenticationManager's authenticate method. The provider chain is a list, and iteration stops at the first successful match. If your OAuth2 provider is later in the list, it never runs. Reorder providers in SecurityFilterChain. Put the most specific providers first.
Symptom · 02
Method-level @PreAuthorize annotations not working in Spring Boot 3.x
→
Fix
Verify you are using @EnableMethodSecurity, not @EnableGlobalMethodSecurity. The old annotation is deprecated. It still compiles but doesn't wire into the new AOP infrastructure. Check the application context for the MethodSecurityInterceptor bean. If it's missing, you're using the wrong annotation.
Symptom · 03
POST requests returning 403 Forbidden with no CSRF token
→
Fix
CSRF protection is enabled by default in Spring Security 6.x. For REST APIs that don't use session-based auth, disable it with http.csrf(AbstractHttpConfigurer::disable). But do it consciously. If you need CSRF, configure the token repository to expose the token via a cookie or header endpoint.
Symptom · 04
OAuth2 Resource Server returns 401 but JWT is valid
→
Fix
Check the NimbusJwtDecoder configuration. In Spring Security 6.x, JWT validation failures don't throw exceptions. They return a 401 with a generic 'Invalid token' message. The real error is in the debug logs. Enable TRACE logging for org.springframework.security.oauth2. Check the JWK set URI is accessible and the public key matches.
★ Debug Cheat SheetCommands for fast diagnosis in production
Add http.csrf(AbstractHttpConfigurer::disable) to your SecurityFilterChain if it's a stateless REST API.
Spring Security 5.x vs 6.x: What Changed
Feature
Spring Security 5.x
Spring Security 6.x
Configuration
WebSecurityConfigurerAdapter subclass
SecurityFilterChain @Bean
Method Security
@EnableGlobalMethodSecurity
@EnableMethodSecurity
CSRF Default
Disabled by default
Enabled by default
AuthenticationProvider
Ordered by declaration
Ordered by @Order or bean dependency
JWT Validation Error
Throws exception
Returns 401 silently
Filter Ordering
Fixed by adapter class
Must specify @Order explicitly
⚙ Quick Reference
2 commands from this guide
File
Command / Code
Purpose
AuthenticationManagerConfig.java
@Configuration
The AuthenticationManager Pipeline
CustomFilterOrdering.java
@Component
FilterOrdering
Key takeaways
1
SecurityFilterChain beans must have explicit @Order. Most specific routes first. This prevents non-deterministic filter selection.
2
AuthenticationProvider chain ordering is invisible. Log it on startup. Put JWT providers before password providers.
3
Always disable CSRF for stateless REST APIs. It's enabled by default in 6.x and blocks POST requests.
4
@EnableMethodSecurity replaces @EnableGlobalMethodSecurity. Mixing them silently breaks all role checks.
5
JWT validation errors are hidden from HTTP responses. Enable TRACE logging for org.springframework.security.oauth2 in staging environments.
Common mistakes to avoid
5 patterns
×
Using WebSecurityConfigurerAdapter in Spring Boot 3.x
Symptom
Compiles but security is missing. All endpoints accessible without authentication.
Fix
Replace with SecurityFilterChain @Bean definitions. Remove the adapter class entirely.
×
Forgetting @Order on multiple SecurityFilterChain beans
Symptom
Intermittent 401s. Different on each restart. Hard to reproduce.
Fix
Add @Order(1), @Order(2), etc. Start with most specific path pattern.
×
Mixing @EnableGlobalMethodSecurity with @EnableMethodSecurity
Symptom
Some @PreAuthorize annotations work. Most don't. No error message.
Fix
Keep only @EnableMethodSecurity. Remove the old annotation and its import.
×
Not disabling CSRF for stateless REST API
Symptom
All POST/PUT/DELETE requests return 403 Forbidden.
Fix
Add .csrf(AbstractHttpConfigurer::disable) to the SecurityFilterChain.
×
Assuming JWT validation errors appear in response body
Symptom
401 with no details. Unable to diagnose why JWT is rejected.
Fix
Enable TRACE logging for org.springframework.security.oauth2 to see real error.
INTERVIEW PREP · PRACTICE MODE
Interview Questions on This Topic
Q01SENIOR
What happens if you define two SecurityFilterChain beans in Spring Secur...
Q02JUNIOR
Why does @PreAuthorize stop working after upgrading to Spring Boot 3.x?
Q03SENIOR
Your OAuth2 API returns 401 on POST requests. The JWT is valid. What do ...
Q04SENIOR
How does the AuthenticationProvider chain work in Spring Security 6.x?
Q05SENIOR
What is the difference between CORS and CSRF in Spring Security?
Q06JUNIOR
How do you debug a '401 with no message' in a Spring Security 6.x OAuth2...
Q07SENIOR
What's the correct way to test Spring Security method-level annotations?
Q08SENIOR
Explain how Spring Security 6.x handles OAuth2 resource server JWT valid...
Q01 of 08SENIOR
What happens if you define two SecurityFilterChain beans in Spring Security 6.x without @Order?
ANSWER
Spring picks one arbitrarily. It uses bean discovery order, which is non-deterministic across restarts. This causes intermittent security failures. Always annotate with @Order, starting from the most specific path.
Q02 of 08JUNIOR
Why does @PreAuthorize stop working after upgrading to Spring Boot 3.x?
ANSWER
The old annotation @EnableGlobalMethodSecurity is deprecated. It doesn't wire into the new AOP infrastructure. Replace it with @EnableMethodSecurity. Remove the old import entirely. Check that the MethodSecurityInterceptor bean exists in the context.
Q03 of 08SENIOR
Your OAuth2 API returns 401 on POST requests. The JWT is valid. What do you check?
ANSWER
First, check if CSRF protection is enabled. For stateless APIs, disable it with .csrf(AbstractHttpConfigurer::disable). Second, check CORS configuration if the request comes from a browser. Third, enable TRACE logging for org.springframework.security.oauth2 to see if the JWT is being rejected for clock skew or signature issues.
Q04 of 08SENIOR
How does the AuthenticationProvider chain work in Spring Security 6.x?
ANSWER
It's a list of AuthenticationProvider beans. Spring iterates through the list. The first provider that returns a non-null Authentication wins. If no provider supports the token type, the request fails. The ordering is critical. Use @Order on provider beans to enforce the sequence. Most specific providers should come first.
Q05 of 08SENIOR
What is the difference between CORS and CSRF in Spring Security?
ANSWER
CORS is a browser security mechanism that restricts cross-origin HTTP requests. It's configured in Spring Security via CorsConfigurationSource. CSRF is a protection against cross-site request forgery attacks. It uses tokens to verify the origin of state-changing requests. For stateless APIs with token-based auth, disable CSRF. CORS still needs explicit configuration for browser clients.
Q06 of 08JUNIOR
How do you debug a '401 with no message' in a Spring Security 6.x OAuth2 resource server?
ANSWER
Enable TRACE logging for org.springframework.security.oauth2 in application.yml. The real error message — expired token, wrong issuer, bad signature — appears in the logs. Also check the JwtDecoder bean. Verify the JWK set URI is accessible. Configure clock skew tolerance if needed.
Q07 of 08SENIOR
What's the correct way to test Spring Security method-level annotations?
ANSWER
Use @SpringBootTest with @AutoConfigureMockMvc. Apply @WithMockUser to test methods to simulate authentication. This avoids needing a real authentication provider. For testing authorization logic, provide a custom PermissionEvaluator bean. Use @ActiveProfiles('test') to avoid overriding production security configuration.
Q08 of 08SENIOR
Explain how Spring Security 6.x handles OAuth2 resource server JWT validation internally.
ANSWER
The JwtDecoder bean decodes and validates the token. It uses Nimbus JOSE JWT library. Validation includes signature verification using the JWK set, expiration check with configurable clock skew, issuer validation, and audience validation. If any check fails, the decoder returns a JwtException. The authentication filter catches this and returns a 401. The filter doesn't expose the specific failure reason in the response for security reasons. You must check TRACE logs.
01
What happens if you define two SecurityFilterChain beans in Spring Security 6.x without @Order?
SENIOR
02
Why does @PreAuthorize stop working after upgrading to Spring Boot 3.x?
JUNIOR
03
Your OAuth2 API returns 401 on POST requests. The JWT is valid. What do you check?
SENIOR
04
How does the AuthenticationProvider chain work in Spring Security 6.x?
SENIOR
05
What is the difference between CORS and CSRF in Spring Security?
SENIOR
06
How do you debug a '401 with no message' in a Spring Security 6.x OAuth2 resource server?
JUNIOR
07
What's the correct way to test Spring Security method-level annotations?
SENIOR
08
Explain how Spring Security 6.x handles OAuth2 resource server JWT validation internally.
SENIOR
FAQ · 5 QUESTIONS
Frequently Asked Questions
01
Why is my POST request getting 403 Forbidden in Spring Security 6.x?
CSRF is enabled by default. For stateless REST APIs, disable it with .csrf(AbstractHttpConfigurer::disable). If it's a browser request, check CORS configuration separately.
Was this helpful?
02
Does @EnableGlobalMethodSecurity still work in Spring Boot 3.x?
It compiles but doesn't wire into the new AOP infrastructure. Many annotations silently stop working. Use @EnableMethodSecurity instead.
Was this helpful?
03
How do I debug a 401 from Spring Security OAuth2 resource server?
Enable TRACE logging for org.springframework.security.oauth2. The real error appears in the logs. Check JWT expiry, clock skew, issuer mismatch, or missing JwtDecoder bean.
Was this helpful?
04
Can I have multiple SecurityFilterChain beans in one application?
Yes. Use @Order annotations. Put the most specific path matchers first (e.g., /api/ before /actuator/). Each bean handles a different path pattern.
Was this helpful?
05
What's the best way to test security in Spring Boot 3.x?
Use @WebMvcTest with @WithMockUser for controller-level tests. For integration tests, use @SpringBootTest with @AutoConfigureMockMvc and @ActiveProfiles('test').