It is generally considered good security practice to adopt a "`deny-by-default`" stance, where you explicitly specify what is allowed and disallow everything else.
In that case, it is easiest to define access configuration attributes for these specific URLs rather than for every secured resource.
Put differently, sometimes it is nice to say `ROLE_SOMETHING` is required by default and allow only certain exceptions to this rule, such as for login, logout, and home pages of an application.
You could also omit these pages from the filter chain entirely, thus bypassing the access control checks, but this may be undesirable for other reasons, particularly if the pages behave differently for authenticated users.
Calls to servlet API calls, such as `getCallerPrincipal`, still return null, even though there is actually an anonymous authentication object in the `SecurityContextHolder`.
There are other situations where anonymous authentication is useful, such as when an auditing interceptor queries the `SecurityContextHolder` to identify which principal was responsible for a given operation.
Three classes work together to provide the anonymous authentication feature.
`AnonymousAuthenticationToken` is an implementation of `Authentication` and stores the `GrantedAuthority` instancesthat apply to the anonymous principal.
There is a corresponding `AnonymousAuthenticationProvider`, which is chained into the `ProviderManager` so that `AnonymousAuthenticationToken` instances are accepted.
Finally, an `AnonymousAuthenticationFilter` is chained after the normal authentication mechanisms and automatically adds an `AnonymousAuthenticationToken` to the `SecurityContextHolder` if there is no existing `Authentication` held there.
The filter and authentication provider is defined as follows:
If you share a `ProviderManager` that contains an `AnonymousAuthenticationProvider` in a scenario where it is possible for an authenticating client to construct the `Authentication` object (such as with RMI invocations), then a malicious client could submit an `AnonymousAuthenticationToken` that it had created itself (with the chosen username and authority list).
If the `key` is guessable or can be found out, the token would be accepted by the anonymous provider.
This is not a problem with normal usage. However, if you use RMI, you should use a customized `ProviderManager` that omits the anonymous provider rather than sharing the one you use for your HTTP authentication mechanisms.
As explained earlier, the benefit of anonymous authentication is that all URI patterns can have security applied to them, as the following example shows:
Rounding out the anonymous authentication discussion is the `AuthenticationTrustResolver` interface, with its corresponding `AuthenticationTrustResolverImpl` implementation.
This interface provides an `isAnonymous(Authentication)` method, which allows interested classes to take into account this special type of authentication status.
The `ExceptionTranslationFilter` uses this interface in processing `AccessDeniedException` instances.
If an `AccessDeniedException` is thrown and the authentication is of an anonymous type, instead of throwing a 403 (forbidden) response, the filter, instead, commences the `AuthenticationEntryPoint` so that the principal can authenticate properly.
This is a necessary distinction. Otherwise, principals would always be deemed "`authenticated`" and never be given an opportunity to login through form, basic, digest, or some other normal authentication mechanism.
We often see the `ROLE_ANONYMOUS` attribute in the earlier interceptor configuration replaced with `IS_AUTHENTICATED_ANONYMOUSLY`, which is effectively the same thing when defining access controls.
This is an example of the use of the `AuthenticatedVoter`, which we cover in the xref:servlet/authorization/architecture.adoc#authz-authenticated-voter[authorization chapter].
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments[Spring MVC resolves parameters of type `Principal`] using its own argument resolver.