Describe the bug
Configuring authorizations using the access() method interferes with authentication in an inconsistent way. Please see repro steps and expected behaviours below for more details.
To Reproduce
Run the project as is. Please note that the access() condition on line 48 of class ProjectConfig (local time before midnight) is always false on purpose.
Use a tool like curl to enter the following requests:
Case 1 (unauthenticated): curl -v http://localhost:8080/hello
Case 2 (authenticated): curl -v -u john:12345 http://localhost:8080/hello
Expected behaviour
Case 1: An error 401 (Unauthorized) is returned. Since there is no rule regarding authentication (there is no isAuthenticated() or similar clause in the access()expression, I would expect an error 403 (Forbidden) since the request is supposedly blocked at the authorization level.
Case 2: An error 403 is returned, which looks more consistent with my hypothesis stating that the request is blocked at the authorization level.
If I changed the method invocation from isBefore() to isAfter() in class ProjectConfig (so that the access() condition is always true), there would be no errors (i.e, response 200) in any case.
In summary, access() applies authentication constraints only when access() conditions are not met, which is an inconsistent behaviour.
Sample
Comment From: sjohnr
Thanks for reaching out @jeffmorin! Apologies for the delay in response.
I would expect an error 403 (Forbidden) since the request is supposedly blocked at the authorization level.
If you enable trace logging for the application (via logging.level.org.springframework.security=trace) you will get a nice picture of what's happening. In fact, you are getting an AccessDeniedException which would typically result in a 403 Forbidden. However, the /error page for Spring Boot (served from the ERROR dispatch) requires authentication by default, adhering to the principle of least privilege. The 401 Unauthorized comes from a separate dispatch that is handling the error.
You can of course authorize the ERROR dispatch if you choose to. I'm going to close this as answered.