Describe the bug The last POST request joins the parameters of all the requests that throw BadCredentialsException by ,.

To Reproduce 1. Clone https://github.com/Edsuns/bad-credentials.git. 2. Run the project. 3. Send 3 POST requests with different data value. 4. See the log printed in console.

Spring Security The last POST request joins the parameters of all the requests that throw BadCredentialsException

The request mapping:

    @PostMapping("/public/issue")
    public String issue(@RequestParam String data) {
        log.debug("Received: {}", data);
        throw new BadCredentialsException("Just an example.", new RuntimeException());
    }

The requests:

### Send POST 1
POST http://localhost:8080/public/issue
Content-Type: application/x-www-form-urlencoded

data=value-1

### Send POST 2
POST http://localhost:8080/public/issue
Content-Type: application/x-www-form-urlencoded

data=value-2

### Send POST 3
POST http://localhost:8080/public/issue
Content-Type: application/x-www-form-urlencoded

data=value-3

Expected behavior Each request should receive its data value separately.

Sample

https://github.com/Edsuns/bad-credentials

Comment From: marcusdacoregio

Hi @Edsuns.

I cloned your repository and tried to simulate the problem, but it works for me:

2021-12-02 14:54:49.069 DEBUG 23534 --- [nio-8080-exec-1] c.e.b.BadCredentialsApplication          : Received: value-1
2021-12-02 14:55:01.602 DEBUG 23534 --- [nio-8080-exec-3] c.e.b.BadCredentialsApplication          : Received: value-2
2021-12-02 14:55:03.026 DEBUG 23534 --- [nio-8080-exec-5] c.e.b.BadCredentialsApplication          : Received: value-3

Are you sure that this problem is related to Spring Security?

Also, if you can create a test that simulates the behavior, it would be easier to simulate.

Comment From: Edsuns

Hi. I tried. TestRestTemplate and MockMvc can not reproduce this issue. You need to make real POST requests with Content-Type application/x-www-form-urlencoded and param data in request body.

Both of these ways can reproduce it:

Spring Security The last POST request joins the parameters of all the requests that throw BadCredentialsException

Spring Security The last POST request joins the parameters of all the requests that throw BadCredentialsException

Comment From: marcusdacoregio

I performed these three requests:

Using curl:

curl -X POST http://localhost:8080/public/issue -H "Content-Type: application/x-www-form-urlencoded" -d "data=value-1"
curl -X POST http://localhost:8080/public/issue -H "Content-Type: application/x-www-form-urlencoded" -d "data=value-2"
curl -X POST http://localhost:8080/public/issue -H "Content-Type: application/x-www-form-urlencoded" -d "data=value-3"

and using httpie:

http --form POST :8080/public/issue data=value-1
http --form POST :8080/public/issue data=value-2
http --form POST :8080/public/issue data=value-3

And yet the logs are fine

2021-12-03 09:31:08.056 DEBUG 50242 --- [nio-8080-exec-1] c.e.b.BadCredentialsApplication          : Received: value-1
2021-12-03 09:31:14.246 DEBUG 50242 --- [nio-8080-exec-2] c.e.b.BadCredentialsApplication          : Received: value-2
2021-12-03 09:31:19.128 DEBUG 50242 --- [nio-8080-exec-4] c.e.b.BadCredentialsApplication          : Received: value-3

Are you sure that there isn't another thing affecting the output?

Comment From: Edsuns

To reproduce it, the requests should bring the cookie JSESSIONID at the same time. JSESSIONID is generated from the first request automatically. So you should run these requests in an environment that supports cookies.

Comment From: marcusdacoregio

Thanks @Edsuns. I can simulate it now. I'll investigate it and come back to you.

Related to https://github.com/spring-projects/spring-security/issues/1130

Comment From: marcusdacoregio

Hi @Edsuns. Talking to @rwinch for some context, this is behaving as expected.

Since you are throwing an AuthenticationException, Spring Security understands that the user is not allowed to access that path, and saves the request in order to redirect the user when they log in or do any other stuff. I want to understand more what is the scenario in a production environment, are you simulating the problem using a CLI or a Browser?

If you are using a CLI, you can disable the request cache like so: http.requestCache(RequestCacheConfigurer::disable).

I'm closing this for now but feel free to continue discussing.

Comment From: Edsuns

I use browser.

To solve the problem, I use throw new ResponseStatusException(HttpStatus.UNAUTHORIZED) instead of throw new BadCredentialsException("message") finally.