skip to content

AuthorizationManager

AuthorizationManager replaced the old AccessDecisionManager and voter model in Spring Security 6, returning a decision for a request or invocation. Knowing the replacement is a quick way to show you are current.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is the AuthorizationManager interface in Spring Security, and what did it replace?

level: juniorimportance: must knowfreq 70%

answer

  1. One SPI: AuthorizationManager<T>
  2. Replaced AccessDecisionManager + voters
  3. Supplier<Authentication> = lazy principal
  4. Returns AuthorizationDecision (granted boolean); null = abstain
  5. Used by AuthorizationFilter + method interceptors

basics

~10 s

AuthorizationManager is Spring Security's interface that decides whether an authenticated user is allowed to access something. In Spring Security 6 it replaced the older AccessDecisionManager and voter system.

solid answer

~30 s

AuthorizationManager<T> is the single decision-making SPI in Spring Security 6. Given the current Authentication (supplied lazily) and the object being secured (type T, e.g. an HTTP request or a method invocation), it returns an AuthorizationDecision saying granted or denied. It replaced the older, more complex AccessDecisionManager + AccessDecisionVoter chain from Spring Security 5.x, which used voters that returned ACCESS_GRANTED / DENIED / ABSTAIN integers. AuthorizationManager is simpler: one interface, generic over what you secure, with ready-made implementations like AuthorityAuthorizationManager (role/authority checks) and AuthenticatedAuthorizationManager (is-the-user-logged-in checks). It's used by AuthorizationFilter for web requests and by method-security interceptors for @PreAuthorize.

code

java · 10 lines
java
// The SPI (simplified, classic form)
public interface AuthorizationManager<T> {
    AuthorizationDecision check(Supplier<Authentication> authentication, T object);
}

// Wiring it into HTTP security
http.authorizeHttpRequests(auth -> auth
    .requestMatchers("/public/**").permitAll()
    .requestMatchers("/admin/**").hasRole("ADMIN")   // AuthorityAuthorizationManager under the hood
    .anyRequest().authenticated());                  // AuthenticatedAuthorizationManager

go deeper

for a junior

Know it's the yes/no access-decision interface and that it replaced the old voter system.

for a middle

Explain the generic <T>, the Supplier<Authentication> laziness, and the granted/abstain semantics.

for a senior

Contrast with AccessDecisionManager/voters and AffirmativeBased strategies; know AuthorizationFilter replaced FilterSecurityInterceptor.

for a principal

Discuss deny-by-default migration risk, the check→authorize/AuthorizationResult evolution, and Observability integration.

## What it is `AuthorizationManager<T>` is the core authorization SPI (Service Provider Interface) in Spring Security 6.x. "Authorization" answers the question *"is this user allowed to do this?"* — as opposed to *authentication*, which answers *"who is this user?"*. The `<T>` type parameter is the thing being protected: for web requests it's `RequestAuthorizationContext` (wraps the `HttpServletRequest`); for method security it's `MethodInvocation` / `MethodInvocationResult`. ## The interface Historically the method was: ```java AuthorizationDecision check(Supplier<Authentication> authentication, T object); ``` In Spring Security 6.4+ that was superseded by `AuthorizationResult authorize(Supplier<Authentication>, T)` (with `AuthorizationDecision implements AuthorizationResult`), but the mental model is identical: input = the caller plus the guarded object, output = a decision. Two details matter: - **`Supplier<Authentication>`** — the `Authentication` is wrapped in a `Supplier` so it is resolved *lazily*. If a rule never needs the principal (e.g. `permitAll`), Spring never pays the cost of loading it. Calling `.get()` on an unauthenticated request can throw `AuthenticationCredentialsNotFoundException`. - **Return value** — `AuthorizationDecision` carries a boolean `isGranted()`. Returning `null` means **abstain** ("I have no opinion"), which lets a combining manager fall through to other rules. ## What it replaced Before 6.x, authorization went through `AccessDecisionManager`, which coordinated a list of `AccessDecisionVoter`s. Each voter returned an `int` constant (`ACCESS_GRANTED`, `ACCESS_DENIED`, `ACCESS_ABSTAIN`) and a strategy (`AffirmativeBased`, `ConsensusBased`, `UnanimousBased`) tallied the votes. This was flexible but verbose and hard to reason about. Spring Security 5.5 introduced `AuthorizationManager`; 5.8/6.0 made it the default and deprecated/removed the voter machinery. `FilterSecurityInterceptor` was replaced by `AuthorizationFilter`. ## Built-in implementations - **`AuthorityAuthorizationManager`** — checks GrantedAuthorities: `hasRole`, `hasAnyRole`, `hasAuthority`, `hasAnyAuthority`. - **`AuthenticatedAuthorizationManager`** — checks authentication *state*: `authenticated`, `fullyAuthenticated`, `rememberMe`, `anonymous`. - **`AuthorizationManagers`** — static combinators: `allOf`, `anyOf`, `not`. - **`WebExpressionAuthorizationManager`** — evaluates a SpEL expression. ## Where it's wired - Web: `authorizeHttpRequests { ... }` builds a `RequestMatcherDelegatingAuthorizationManager` that maps request matchers to `AuthorizationManager`s; `AuthorizationFilter` invokes it. - Method security: `@EnableMethodSecurity` registers `AuthorizationManagerBeforeMethodInterceptor` / `AuthorizationManagerAfterMethodInterceptor` for `@PreAuthorize` / `@PostAuthorize`. ## Gotcha Since 6.0, web authorization is **deny-by-default**: any request not matched by a rule is denied, and Spring throws if you leave requests unmapped. Always end with `anyRequest().authenticated()` or `.denyAll()`.

  • Why is the Authentication passed as a Supplier rather than a plain Authentication?
    So it's resolved lazily — rules like permitAll never need the principal, so Spring avoids resolving it (and avoids throwing for unauthenticated requests) unless a rule actually calls .get().
  • What does returning null from an AuthorizationManager mean?
    Abstain — no decision. A delegating/combining manager treats it as 'no opinion' and moves on; it is not the same as denying.

saying these in an interview costs you the question

  • Saying AuthorizationManager handles authentication (login) — it only handles authorization.
  • Claiming it still uses voters returning int constants — that's the removed AccessDecisionVoter model.
  • Thinking null means 'deny' rather than 'abstain'.

context

open as a page

Compare AuthorityAuthorizationManager and AuthenticatedAuthorizationManager. When does each apply?

level: middleimportance: should knowfreq 55%

basics

~10 s

AuthorityAuthorizationManager 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.

open as a page

How do you write a custom AuthorizationManager and plug it into method security or HTTP authorization?

level: seniorimportance: should knowfreq 40%

basics

~10 s

Implement AuthorizationManager<T> (T = RequestAuthorizationContext for web or MethodInvocation for methods) and return an AuthorizationDecision. Wire it via .access(manager) in authorizeHttpRequests, or register an AuthorizationManagerBeforeMethodInterceptor for method security.

open as a page

Explain AuthorizationDecision and how abstaining works when composing AuthorizationManagers with allOf/anyOf.

level: seniorimportance: should knowfreq 45%

basics

~10 s

AuthorizationDecision wraps a boolean 'granted' result. An AuthorizationManager can also return null to abstain (no opinion). AuthorizationManagers.anyOf grants if any manager grants; allOf grants only if all grant and none deny.

open as a page

What changed architecturally moving from AccessDecisionManager/voters to AuthorizationManager, and what migration risks does deny-by-default introduce?

level: principalimportance: nice to knowfreq 30%

basics

~10 s

Spring Security replaced the voter-based AccessDecisionManager with a single AuthorizationManager SPI, and swapped FilterSecurityInterceptor for AuthorizationFilter. Since 6.0, web authorization is deny-by-default: any request not explicitly matched is denied, so incomplete rules break access.

open as a page