spring-projects / spring-projects/spring-security
DefaultAuthorizationManagerFactory.anonymous() applies additionalAuthorization
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
Describe the bug
DefaultAuthorizationManagerFactory.anonymous() applies the configured additionalAuthorization, which contradicts the documented contract of setAdditionalAuthorization(...):
This does not affect
anonymous,permitAll, ordenyAll.
permitAll() and denyAll() are correctly unaffected, but anonymous() is affected.
To Reproduce
DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>();
// any additional gate that an anonymous user cannot satisfy (e.g. an MFA factor requirement)
factory.setAdditionalAuthorization((authentication, object) -> new AuthorizationDecision(false));
AuthorizationManager<String> anonymous = factory.anonymous();
Authentication anonymousToken = new AnonymousAuthenticationToken("key", "anonymousUser",
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
// Expected (per the contract): granted, because anonymous() is not affected by additionalAuthorization
boolean granted = anonymous.authorize(() -> anonymousToken, "").isGranted();
// Actual: false
Equivalently, when configured through AuthorizationManagerFactories.multiFactor().requireFactors(...), anonymous requests are denied because an anonymous user holds none of the required factors.
Expected behavior
anonymous() is not affected by additionalAuthorization (as documented), so an anonymous authentication is granted.
Root cause
anonymous() routes through the same createManager(AuthenticatedAuthorizationManager) path as authenticated(), fullyAuthenticated(), and rememberMe(), which wraps the manager via withAdditionalAuthorization(...). permitAll() and denyAll() are inherited interface defaults and never go through that path, so they remain unaffected.
I will submit a PR with a regression test.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at DefaultAuthorizationManagerFactory.anonymous() and trace its createManager(AuthenticatedAuthorizationManager) and withAdditionalAuthorization path. Add the regression test described in the issue, then verify that anonymous() remains granted when additionalAuthorization denies access while authenticated() behavior is unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- authorization, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100