Java
javaTutorial
In-depth understanding of CSRF protection and POST request authentication exceptions in Spring Security
In-depth understanding of CSRF protection and POST request authentication exceptions in Spring Security

This article deeply explores the problem that POST requests may encounter `InsufficientAuthenticationException` in the integrated environment of Spring Security and JWT. This exception usually originates from Spring Security's cross-site request forgery (CSRF) protection mechanism, which requires submission of a CSRF token for HTTP methods that modify state (such as POST, PUT, DELETE). The article will explain how CSRF works, why GET requests are not affected, and provide guidance on how to correctly handle such authentication exceptions without disabling CSRF.
In applications that integrate Spring Security and JWT, developers may encounter a common problem: HTTP GET requests can pass authentication and authorization normally, but when sending HTTP POST requests, they receive an org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource exception. Although this problem can be solved by adding .csrf().disable() in the Spring Security configuration, the rationale behind it and whether CSRF protection should be disabled is often confusing.
What is a CSRF attack?
Cross-Site Request Forgery (CSRF) is a malicious attack in which an attacker induces users to visit a malicious website, which uses the user's logged-in identity to send forged requests to trusted websites. Since the browser will automatically carry the user's session cookie on the trusted website, the trusted website will mistakenly believe that the request is initiated by the user, and thus perform the attacker's preset operations, such as changing passwords, transferring money, etc.
Spring Security’s CSRF protection mechanism
In order to prevent CSRF attacks, Spring Security provides a powerful CSRF protection mechanism. The core principle is that each HTTP request that needs to modify the status (such as POST, PUT, PATCH, DELETE) is mandatory to contain a special, randomly generated CSRF token (token). This token is usually embedded in the HTML by the server when rendering the page, or sent to the client via a cookie. When the client sends a request to modify the status, this token must be submitted to the server, and the server will verify the validity of the token.
Why are GET requests not affected?
GET requests are generally designed to be idempotent and should not cause changes to server-side state (e.g., just retrieving data). Therefore, Spring Security does not enforce CSRF tokens for GET requests by default. This is why in the above scenario, the GET request works fine but the POST request fails. A POST request is intended to submit data and possibly modify server state, so it must follow CSRF protection rules.
How CSRF tokens work
When Spring Security detects that an HTTP request is a POST, PUT, PATCH or DELETE method, it checks whether the request contains a valid CSRF token. If the token is missing from the request, or the token is invalid, Spring Security will throw an InsufficientAuthenticationException, indicating that "full authentication is required to access this resource." "Complete authentication" here not only refers to user identity authentication, but also includes verifying the legitimacy of the request source through the CSRF token.
How to handle InsufficientAuthenticationException with CSRF
There are two main strategies for handling this exception: integrating a CSRF token or disabling CSRF protection.
1. Integrate CSRF token (recommended for browser-based applications)
For traditional web applications (such as using template engines such as Thymeleaf and JSP to render pages), Spring Security will automatically add CSRF tokens to forms or meta tags. When the client initiates a POST request, it needs to send this token as a request parameter or request header.
-
Obtain the CSRF token: Typically, the CSRF token is provided via:
- Hidden fields in HTML forms:
- Meta tags: and
- Cookie: Spring Security can store CSRF tokens in a cookie called XSRF-TOKEN.
-
Send CSRF token: When the client (such as JavaScript) initiates an Ajax POST request, it needs to obtain the token from the above source and send it as a request header (usually X-CSRF-TOKEN) or a request parameter (usually _csrf).
// Example: Use jQuery to send an Ajax request and include the CSRF token $(function () { var token = $("meta[name='_csrf']").attr("content"); var header = $("meta[name='_csrf_header']").attr("content"); // Set the CSRF request header before all Ajax requests $(document).ajaxSend(function(e, xhr, options) { if (options.type !== 'GET') { // Add CSRF token only to non-GET requests xhr.setRequestHeader(header, token); } }); // Example POST request $('#myForm').submit(function(event) { event.preventDefault(); $.ajax({ url: '/api/v1/users', type: 'POST', data: $(this).serialize(), success: function(response) { console.log("Success:", response); }, error: function(xhr, status, error) { console.error("Error:", error); } }); }); });
2. Disable CSRF protection (applicable to pure API services or specific scenarios)
If your application is a pure RESTful API service that does not serve any web pages, or is a mobile application backend, and you have ensured authentication and authorization of requests through other mechanisms (such as JWT tokens, OAuth2, etc.), then disabling CSRF protection may be acceptable. In this case, the client typically does not process the HTML page and therefore cannot obtain and submit the CSRF token.
Note: Disabling CSRF puts your application at risk of CSRF attacks. Be sure to disable only after fully understanding the risks and confirming that additional security measures are in place (for example, ensuring that all API requests are protected with authentication tokens and that these tokens are not automatically sent by the browser).
Code Example: Disabling CSRF
In your SecurityConfig, disable CSRF protection by calling the .csrf().disable() method:
@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecuritySecurityConfigurerAdapter {
private final JwtFilter jwtFilter;
private final exceptionHandler exceptionHandler; // Assume this is an AuthenticationEntryPoint
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().disable()
.csrf().disable() // Disable CSRF protection.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/v1/users/**").hasAnyRole("USER")
.antMatchers("/api/v1/admin/**").hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.addFilterBefore(jwtFilter, FilterSecurityInterceptor.class)
.exceptionHandling().authenticationEntryPoint(exceptionHandler);
}
}
After adding .csrf().disable(), Spring Security will no longer check the CSRF token in POST, PUT, PATCH, and DELETE requests, thereby avoiding InsufficientAuthenticationException.
Summarize
InsufficientAuthenticationException occurs in POST requests, usually Spring Security's CSRF protection mechanism is at work. It is crucial to understand how CSRF attacks work and how Spring Security protects against such attacks through CSRF tokens. For traditional web applications, it is recommended to integrate CSRF tokens to enhance security; while for pure API services, you can consider disabling CSRF protection after assessing the risks and ensuring that alternative security measures are in place. Correctly configuring and managing CSRF protection is a key part of building robust and secure Spring Security applications.
The above is the detailed content of In-depth understanding of CSRF protection and POST request authentication exceptions in Spring Security. For more information, please follow other related articles on the PHP Chinese website!
Hot AI Tools
Undress AI Tool
Undress images for free
AI Clothes Remover
Online AI tool for removing clothes from photos.
Undresser.AI Undress
AI-powered app for creating realistic nude photos
ArtGPT
AI image generator for creative art from text prompts.
Stock Market GPT
AI powered investment research for smarter decisions
Hot Article
Popular tool
Notepad++7.3.1
Easy-to-use and free code editor
SublimeText3 Chinese version
Chinese version, very easy to use
Zend Studio 13.0.1
Powerful PHP integrated development environment
Dreamweaver CS6
Visual web development tools
SublimeText3 Mac version
God-level code editing software (SublimeText3)
Hot Topics
20518
7
13631
4
How to configure Spark distributed computing environment in Java_Java big data processing
Mar 09, 2026 pm 08:45 PM
Spark cannot run in local mode, ClassNotFoundException: org.apache.spark.sql.SparkSession. This is the most common first step of getting stuck: even the dependencies are not correct. Only spark-core_2.12 is written in Maven, but spark-sql_2.12 is not added. SparkSession crashes as soon as it is built. The Scala version must strictly match the official Spark compiled version - Spark3.4.x uses Scala2.12 by default. If you use spark-sqljar of 2.13, the class loader cannot directly find the main class. Practical advice: Go to mvnre
How to safely map user-entered weekday string to integer value and implement date offset operation in Java
Mar 09, 2026 pm 09:43 PM
This article introduces a concise and maintainable way to map the weekday string (such as "Monday") to the corresponding serial number (1-7), and use the modulo operation to realize the forward and backward offset of any number of days (such as Monday plus 4 days to get Friday), avoiding lengthy if chains and hard-coded logic.
How to generate a list of duplicate elements using Java's Collections.nCopies_Initialization tips
Mar 06, 2026 am 06:24 AM
Collections.nCopies returns an immutable view. Calling add/remove will throw UnsupportedOperationException; it needs to be wrapped with newArrayList() to modify it, and it is disabled for mutable objects.
How to use Homebrew to install Java on Mac_A must-have Java tool chain for developers
Mar 09, 2026 pm 09:48 PM
Homebrew installs the latest stable version of openjdk (such as JDK22) by default, not the LTS version; you need to explicitly execute brewinstallopenjdk@17 or brewinstallopenjdk@21 to install the LTS version, and manually configure PATH and JAVA_HOME to be correctly recognized by the system and IDE.
What is exception masking (Suppressed Exceptions) in Java_Multiple resource shutdown exception handling
Mar 10, 2026 pm 06:57 PM
What is SuppressedException: It is not "swallowed", but actively archived by the JVM. SuppressedException is not an exception loss, but the JVM quietly attaches the secondary exception to the main exception under the premise that "only one exception must be thrown" for you to verify afterwards. It is automatically triggered by the JVM in only two scenarios: one is that the resource closure in try-with-resources fails, and the other is that you manually call addSuppressed() in finally. The key difference is: the former is fully automatic and safe; the latter requires you to keep it to yourself, and it can be written as shadowing if you are not careful. try-
How to correctly implement runtime file writing in Java applications (avoiding JAR internal write failures)
Mar 09, 2026 pm 07:57 PM
After a Java application is packaged as a JAR, data cannot be written directly to the resources in the JAR package (such as test.txt) because the JAR is essentially a read-only ZIP archive; the correct approach is to write variable data to an external path (such as a user directory, a temporary directory, or a configuration-specified path).
What is the underlying principle of array expansion in Java_Java memory dynamic adjustment analysis
Mar 09, 2026 pm 09:45 PM
ArrayList.add() triggers expansion because grow() is called when size is equal to elementData.length. The first add allocates 10 capacity, and subsequent expansion is 1.5 times and not less than the minimum requirement, relying on delayed initialization and System.arraycopy optimization.
How to safely read a line of integer input in Java and avoid Scanner blocking
Mar 06, 2026 am 06:21 AM
This article introduces typical blocking problems when using Scanner to read multiple integers in a single line. It points out that hasNextInt() will wait indefinitely when there is no subsequent input, and recommends a safe alternative with nextLine() string splitting as the core.





