matrei opened a new pull request, #16375:
URL: https://github.com/apache/grails-core/pull/16375

   Fixes the flaky `UserControllerSpec` in `grails-test-examples/scaffolding`.
   
   ### What was happening
   
   The Geb reports from the failed CI runs (e.g. 
[34315721364](https://github.com/apache/grails-core/actions/runs/34315721364), 
[35675996625](https://github.com/apache/grails-core/actions/runs/35675996625)) 
all capture the same page when the 30 s login wait expires: a pristine Spring 
Security login page — no "Bad credentials" message, empty fields. The `POST 
/login` had succeeded, and the browser was bounced back to `/login` afterwards.
   
   A Tomcat access log with the session cookie and `Set-Cookie` headers shows 
why:
   
   ```
   GET /login?logout   200 cookie=27BA set=JSESSIONID=43F6   <- previous spec's 
logout
   GET /community/user/index 302 cookie=- set=JSESSIONID=42C8 <- next spec 
already started
   GET /login          200 cookie=42C8
   GET /favicon.ico    302 cookie=43F6 -> /login              <- stale favicon 
fetch for /login?logout
   GET /favicon.ico    302 cookie=42C8 -> /login              <- favicon fetch 
for the current login page
   GET /login          200 cookie=42C8                        <- the favicon's 
redirect chain
   POST /login         302 cookie=42C8 set=JSESSIONID=6524 ...
   ```
   
   Spring Security's generated login and logout pages declare no icon, so 
Chrome fetches `/favicon.ico` for them on its own — at low priority, 
asynchronously, sometimes well into the next spec. Under Boot's default chain 
(everything authenticated) that fetch is bounced through `/login`, which 
renders a CSRF token and therefore **creates a session and sends `Set-Cookie`** 
whenever the cookie it carries is stale — which it is right after a login 
(session id changed) or a logout (session invalidated). When that straggling 
`Set-Cookie` lands between the login redirect and the page it leads to, it 
overwrites the authenticated session and the browser lands on a fresh login 
page.
   
   That is why the earlier rounds of longer / more specific waits in 
`LoginPage` and `LogoutPage` never cured it: the browser really is on a fresh 
login page.
   
   ### The fix
   
   - An explicit `SecurityFilterChain` in `Application` that keeps Boot's 
defaults (form login + basic, everything else authenticated) but permits 
`/favicon.ico` and `/assets/**`. The assets matter independently of the 
favicon: a late asset request (e.g. the icon font pulled in by CSS) carrying a 
just-invalidated cookie is bounced the same way.
   - `/favicon.ico` mapped to the asset-pipeline icon the layout already uses. 
Permitting alone is not enough — Grails 404s it, Tomcat forwards to `/error`, 
and that ERROR dispatch runs through the security chain again (verified: still 
a `Set-Cookie`).
   
   Verified with `curl` and a stale cookie: `/favicon.ico` → 301 → 
`/assets/favicon.ico` → 200 with no `Set-Cookie` anywhere; `/user/index` still 
redirects to `/login`. `:grails-test-examples-scaffolding:integrationTest` 
passes 3/3 consecutive local runs; `codeStyle` is clean.
   
   The same app and specs exist on 7.0.x / 7.2.x, but I found no occurrence of 
this failure in their recent CI runs, so this targets 8.0.x only.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to