Compare AuthorityAuthorizationManager and AuthenticatedAuthorizationManager. When does each apply?
answer
- Authority = has role/authority; Authenticated = login state
- hasRole prepends ROLE_; hasAuthority is literal
- authenticated vs fullyAuthenticated vs rememberMe vs anonymous
- fullyAuthenticated excludes remember-me (step-up)
- Both are AuthorizationManager impls behind the DSL
basics
~10 sAuthorityAuthorizationManager checks whether the user has specific roles/authorities (like hasRole('ADMIN')). AuthenticatedAuthorizationManager only checks whether the user is logged in — authenticated, fully authenticated, remember-me, or anonymous — regardless of roles.
solid answer
~30 sBoth are built-in AuthorizationManager implementations, but they answer different questions. AuthorityAuthorizationManager inspects the Authentication's GrantedAuthorities: its factory methods hasRole, hasAnyRole, hasAuthority, hasAnyAuthority back the DSL calls of the same name. hasRole/hasAnyRole prepend the ROLE_ prefix, so hasRole("ADMIN") matches authority ROLE_ADMIN, while hasAuthority("ADMIN") matches ADMIN literally. AuthenticatedAuthorizationManager checks authentication *state*, not authorities: authenticated() grants any non-anonymous principal; fullyAuthenticated() rejects remember-me logins; rememberMe() and anonymous() match those specific states. Use AuthorityAuthorizationManager when access depends on permissions/roles; use AuthenticatedAuthorizationManager when 'any logged-in user' is enough or you need to distinguish a freshly-authenticated session from a remember-me one (e.g. force re-login before changing a password).
code
java · 13 lines@Bean
SecurityFilterChain chain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
// AuthorityAuthorizationManager — needs ROLE_ADMIN authority
.requestMatchers("/admin/**").hasRole("ADMIN")
// literal authority, no ROLE_ prefix
.requestMatchers("/reports/**").hasAuthority("REPORT_READ")
// AuthenticatedAuthorizationManager — must re-auth, not remember-me
.requestMatchers("/account/password").fullyAuthenticated()
// any logged-in user
.anyRequest().authenticated());
return http.build();
}go deeper
Know one checks roles, the other checks 'is logged in'.
Explain the ROLE_ prefix and the authenticated/fullyAuthenticated/rememberMe/anonymous variants.
Tie DSL methods to the concrete managers and use anyOf/allOf to compose; know the step-up use case.
Reason about remember-me security posture, custom authority prefixes, and abstain behaviour inside combinators.
## Two different questions Spring Security ships several concrete `AuthorizationManager`s. The two most common answer distinct questions: ### AuthorityAuthorizationManager — "does the user have this permission?" It reads the `Collection<GrantedAuthority>` on the `Authentication` and grants if the required authority is present. Static factories: - `hasRole(String)` / `hasAnyRole(String...)` - `hasAuthority(String)` / `hasAnyAuthority(String...)` **The ROLE_ prefix gotcha:** `hasRole("ADMIN")` internally requires the authority `ROLE_ADMIN` — it prepends `ROLE_` for you. `hasAuthority("ADMIN")` requires exactly `ADMIN`. Mixing these up is the classic bug: a user granted `ROLE_ADMIN` passes `hasRole("ADMIN")` but fails `hasAuthority("ADMIN")`. You can customise the prefix, but the default is `ROLE_`. ### AuthenticatedAuthorizationManager — "is the user logged in (and how)?" It ignores authorities and inspects authentication *state*. Factories: - `authenticated()` — any authenticated, non-anonymous principal. - `fullyAuthenticated()` — authenticated **and not** via remember-me (i.e. entered credentials this session). - `rememberMe()` — authenticated specifically through a remember-me token. - `anonymous()` — the anonymous (not-logged-in) principal. The distinction between `authenticated()` and `fullyAuthenticated()` exists for sensitive operations: a remember-me user is 'logged in' for browsing but you may want them to re-enter credentials before, say, changing account settings — guard that path with `fullyAuthenticated()`. ## How they connect to the DSL These aren't usually instantiated by hand. In `authorizeHttpRequests`: ```java .requestMatchers("/admin/**").hasRole("ADMIN") // -> AuthorityAuthorizationManager.hasRole("ADMIN") .requestMatchers("/account/**").fullyAuthenticated() // -> AuthenticatedAuthorizationManager.fullyAuthenticated() .anyRequest().authenticated() // -> AuthenticatedAuthorizationManager.authenticated() ``` Each DSL method constructs the matching manager and registers it against the request matcher inside a `RequestMatcherDelegatingAuthorizationManager`. ## Combining them Use `AuthorizationManagers.anyOf(...)` / `allOf(...)` to compose, e.g. grant if the user has ROLE_ADMIN *or* is at least fully authenticated. When invoked directly, `AuthenticatedAuthorizationManager` may return `null` (abstain) for the anonymous case in some variants, which matters inside combinators. ## When to use which - Role/permission gating (admin area, feature flags by authority) → **AuthorityAuthorizationManager**. - 'Any signed-in user' or step-up sensitivity (fully vs remember-me) → **AuthenticatedAuthorizationManager**.
- A user has authority ROLE_ADMIN but hasAuthority("ADMIN") denies them. Why?hasAuthority does a literal match against 'ADMIN'; the user's authority is 'ROLE_ADMIN'. hasRole("ADMIN") would work because it prepends the ROLE_ prefix.
- When would you choose fullyAuthenticated() over authenticated()?For sensitive actions (password/email change, payment) where a remember-me session shouldn't suffice — fullyAuthenticated() forces the user to have authenticated with real credentials this session.
saying these in an interview costs you the question
- Claiming hasAuthority("ADMIN") and hasRole("ADMIN") are equivalent.
- Saying AuthenticatedAuthorizationManager checks roles — it checks login state only.
- Thinking fullyAuthenticated() and authenticated() are the same for remember-me users.