Add the cors-csrf module
This commit is contained in:
73
cors-csrf/docs/04-preflight-handlers.md
Normal file
73
cors-csrf/docs/04-preflight-handlers.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 4. `PreFlightRequestHandler`, and the wildcard that is not allowed
|
||||
|
||||
*Prev: [3. The three identical 403s](03-three-identical-403s.md) · Next: [5. The /error dispatch](05-the-error-dispatch.md)*
|
||||
|
||||
## `preFlightRequestHandler`
|
||||
|
||||
`CorsConfigurer` in 7.1.1 has a second setter beside `configurationSource`:
|
||||
|
||||
```java
|
||||
public CorsConfigurer<H> preFlightRequestHandler(PreFlightRequestHandler handler);
|
||||
```
|
||||
|
||||
When one is selected, Spring Security registers Spring Framework's `PreFlightRequestFilter`
|
||||
**before** `CorsFilter` in the chain — `addFilterBefore(.., CorsFilter.class)`, which lands
|
||||
it at 999. It is for applications that answer preflights from their own routing rather than from
|
||||
a `CorsConfiguration`, and it is the hook `WebFlux`-style functional routing and gateway-shaped
|
||||
applications want.
|
||||
|
||||
The handler is picked up either from the `preFlightRequestHandler(..)` call or from a
|
||||
`PreFlightRequestHandler` bean, and only when no `CorsConfigurationSource` or `CorsFilter` was
|
||||
chosen for that chain. Configuring both raises, at startup:
|
||||
|
||||
```
|
||||
java.lang.IllegalStateException: Cannot configure both a CorsConfigurationSource and a
|
||||
PreFlightRequestHandler on CorsConfigurer
|
||||
```
|
||||
|
||||
That string is in `CorsConfigurer.configure`'s constant pool; it is a hard failure, not a
|
||||
warning.
|
||||
|
||||
## `allowedOrigins("*")` with `allowCredentials(true)`
|
||||
|
||||
The Fetch standard forbids answering a credentialed request with
|
||||
`Access-Control-Allow-Origin: *`. Spring enforces it — but not where you would expect.
|
||||
|
||||
The configuration builds. The context starts. The check happens on the first request, inside
|
||||
`CorsConfiguration.validateAllowCredentials`, reached from `checkOrigin`:
|
||||
|
||||
```
|
||||
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain
|
||||
the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response
|
||||
header. To allow credentials to a set of origins, list them explicitly or consider using
|
||||
"allowedOriginPatterns" instead.
|
||||
at org.springframework.web.cors.CorsConfiguration.validateAllowCredentials(CorsConfiguration.java:552)
|
||||
at org.springframework.web.cors.CorsConfiguration.checkOrigin(CorsConfiguration.java:678)
|
||||
at org.springframework.web.cors.DefaultCorsProcessor.checkOrigin(DefaultCorsProcessor.java:193)
|
||||
```
|
||||
|
||||
And here is the part worth knowing: **the client does not get a 500.** It gets a `401`.
|
||||
[`docs/output/07-wildcard-credentials.txt`](output/07-wildcard-credentials.txt) shows a request
|
||||
with entirely correct Basic credentials answered `401 WWW-Authenticate: Basic`. Chapter 5 is why.
|
||||
|
||||
The fix is `setAllowedOriginPatterns(..)`, which echoes the request's own origin back instead of
|
||||
a literal asterisk, and is therefore legal with credentials:
|
||||
|
||||
```java
|
||||
configuration.setAllowedOriginPatterns(List.of("https://*.example.com"));
|
||||
configuration.setAllowCredentials(true);
|
||||
```
|
||||
|
||||
`allowedHeaders("*")` and `allowedMethods("*")` are unaffected — the prohibition is
|
||||
specific to the origin, because that is the one that gets reflected into a header the browser
|
||||
uses to decide whether the caller may read a credentialed response.
|
||||
|
||||
## Private Network Access
|
||||
|
||||
`DefaultCorsProcessor` in Spring Framework 7.0.9 also handles
|
||||
`Access-Control-Request-Private-Network` / `Access-Control-Allow-Private-Network` — both
|
||||
strings are in the class. If a public-origin SPA calls something on a private address, that is
|
||||
the header pair to look for, and `CorsConfiguration.setAllowPrivateNetwork(true)` is the switch.
|
||||
|
||||
---
|
||||
*Prev: [3. The three identical 403s](03-three-identical-403s.md) · Next: [5. The /error dispatch](05-the-error-dispatch.md)*
|
||||
Reference in New Issue
Block a user