docs
Authorization in Spring Security Core provides a comprehensive framework for making access control decisions. This includes both imperative and reactive authorization managers, decision objects, and various built-in authorization strategies.
Core Capabilities:
AuthorizationManager - Main interface for authorization decisionsReactiveAuthorizationManager - Reactive version for WebFluxAuthorizationDecision - Result of authorization check (granted/denied)AuthorizationResult - Extended result with additional metadataAuthorityAuthorizationManager, AuthenticatedAuthorizationManager, AllAuthoritiesAuthorizationManager, AllRequiredFactorsAuthorizationManagerAuthorizationManagers - Utility for combining managers (anyOf, allOf)ObservationAuthorizationManager - Micrometer observation supportKey Interfaces and Classes:
AuthorizationManager<T> - Interface: check(Supplier<Authentication>, T)ReactiveAuthorizationManager<T> - Interface: check(Mono<Authentication>, T)AuthorizationDecision - Class: isGranted(), getAttributes()AuthorizationResult - Class: isGranted(), getAuthorities(), getFactors()AuthorityAuthorizationManager - Checks for specific authoritiesAuthenticatedAuthorizationManager - Checks authentication stateAllAuthoritiesAuthorizationManager - Requires all specified authoritiesAllRequiredFactorsAuthorizationManager - Requires all specified factorsAuthorizationManagers - Static utilities for combining managersObservationAuthorizationManager - Wraps manager with observationDefault Behaviors:
AuthorizationDecision defaults to denied (granted=false)AuthorityAuthorizationManager requires any of the specified authoritiesAuthenticatedAuthorizationManager checks if user is authenticatedAllAuthoritiesAuthorizationManager requires all specified authoritiesAllRequiredFactorsAuthorizationManager requires all specified factorsAuthorizationManagers.anyOf() grants if any manager grantsAuthorizationManagers.allOf() grants only if all managers grantThreading Model:
AuthorizationDecision is immutable (thread-safe)Mono<Authentication>Lifecycle:
Exceptions:
Edge Cases:
AuthorityAuthorizationManager deniesAllRequiredFactorsAuthorizationManager requires allanyOf/allOf short-circuit appropriatelyMain interface for making authorization decisions. Implementations check whether an authenticated user has access to a specific object.
package org.springframework.security.authorization;
interface AuthorizationManager<T> {
@Nullable AuthorizationDecision check(
Supplier<Authentication> authentication,
T object);
}Key Methods:
@Nullable AuthorizationDecision check(
Supplier<Authentication> authentication,
T object)AuthorizationDecision if a decision can be made, null otherwise.Supplier<Authentication> allows lazy evaluation of authentication.Generic Type:
T - The type of object being authorized (e.g., RequestAuthorizationContext, MethodInvocation)Example:
AuthorizationManager<RequestAuthorizationContext> manager = ...;
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
AuthorizationDecision decision = manager.check(() -> auth, context);
if (decision != null && decision.isGranted()) {
// Access granted
} else {
// Access denied
}Reactive version of AuthorizationManager for use in reactive applications (WebFlux).
package org.springframework.security.authorization;
interface ReactiveAuthorizationManager<T> {
Mono<AuthorizationDecision> check(
Mono<Authentication> authentication,
T object);
}Key Methods:
Mono<AuthorizationDecision> check(
Mono<Authentication> authentication,
T object)Mono that emits the authorization decision.Example:
ReactiveAuthorizationManager<RequestAuthorizationContext> manager = ...;
Mono<Authentication> auth = ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication);
Mono<AuthorizationDecision> decision = manager.check(auth, context);
decision
.filter(AuthorizationDecision::isGranted)
.switchIfEmpty(Mono.error(new AccessDeniedException("Access denied")))
.block();Represents the result of an authorization check.
package org.springframework.security.authorization;
class AuthorizationDecision {
AuthorizationDecision(boolean granted);
AuthorizationDecision(boolean granted, Map<String, Object> attributes);
boolean isGranted();
Map<String, Object> getAttributes();
}Constructors:
AuthorizationDecision(boolean granted)AuthorizationDecision(boolean granted, Map<String, Object> attributes)Key Methods:
boolean isGranted()true if access is granted, false otherwise.Map<String, Object> getAttributes()Constants:
static final AuthorizationDecision GRANTED = new AuthorizationDecision(true);
static final AuthorizationDecision DENIED = new AuthorizationDecision(false);Example:
// Simple granted decision
AuthorizationDecision granted = new AuthorizationDecision(true);
// Decision with attributes
Map<String, Object> attrs = new HashMap<>();
attrs.put("reason", "User has admin role");
attrs.put("priority", 1);
AuthorizationDecision decision = new AuthorizationDecision(true, attrs);
// Using constants
AuthorizationDecision allow = AuthorizationDecision.GRANTED;
AuthorizationDecision deny = AuthorizationDecision.DENIED;
// Check decision
if (decision.isGranted()) {
Map<String, Object> metadata = decision.getAttributes();
// Process metadata
}Extended authorization result that includes information about authorities and factors used in the decision.
package org.springframework.security.authorization;
class AuthorizationResult {
AuthorizationResult(boolean granted);
AuthorizationResult(
boolean granted,
Collection<? extends GrantedAuthority> authorities,
Collection<String> factors);
boolean isGranted();
Collection<? extends GrantedAuthority> getAuthorities();
Collection<String> getFactors();
}Constructors:
AuthorizationResult(boolean granted)AuthorizationResult(
boolean granted,
Collection<? extends GrantedAuthority> authorities,
Collection<String> factors)Key Methods:
boolean isGranted()true if access is granted.Collection<? extends GrantedAuthority> getAuthorities()Collection<String> getFactors()Example:
Collection<GrantedAuthority> authorities =
AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_USER");
Collection<String> factors = Arrays.asList("PASSWORD", "OTP");
AuthorizationResult result = new AuthorizationResult(
true,
authorities,
factors
);
if (result.isGranted()) {
Collection<? extends GrantedAuthority> usedAuthorities =
result.getAuthorities();
Collection<String> usedFactors = result.getFactors();
// Process authorities and factors
}Checks if the authentication has any of the specified authorities.
package org.springframework.security.authorization;
class AuthorityAuthorizationManager implements AuthorizationManager<Object> {
AuthorityAuthorizationManager();
void setAuthority(String authority);
void setAuthorities(String... authorities);
void setAuthorities(Collection<String> authorities);
@Nullable AuthorizationDecision check(
Supplier<Authentication> authentication,
Object object);
}Key Methods:
void setAuthority(String authority)void setAuthorities(String... authorities)void setAuthorities(Collection<String> authorities)Behavior:
Example:
AuthorityAuthorizationManager manager = new AuthorityAuthorizationManager();
manager.setAuthorities("ROLE_ADMIN", "ROLE_STAFF");
Authentication adminAuth = new UsernamePasswordAuthenticationToken(
"admin",
"password",
AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_USER")
);
AuthorizationDecision decision = manager.check(() -> adminAuth, null);
// decision.isGranted() == true (has ROLE_ADMIN)
Authentication userAuth = new UsernamePasswordAuthenticationToken(
"user",
"password",
AuthorityUtils.createAuthorityList("ROLE_USER")
);
AuthorizationDecision denied = manager.check(() -> userAuth, null);
// denied.isGranted() == false (no ROLE_ADMIN or ROLE_STAFF)Checks if the authentication is authenticated (not anonymous).
package org.springframework.security.authorization;
class AuthenticatedAuthorizationManager implements AuthorizationManager<Object> {
AuthenticatedAuthorizationManager();
@Nullable AuthorizationDecision check(
Supplier<Authentication> authentication,
Object object);
}Behavior:
isAuthenticated() returns true.Example:
AuthenticatedAuthorizationManager manager = new AuthenticatedAuthorizationManager();
// Authenticated user
Authentication auth = new UsernamePasswordAuthenticationToken(
"user",
"password",
AuthorityUtils.createAuthorityList("ROLE_USER")
);
auth.setAuthenticated(true);
AuthorizationDecision decision = manager.check(() -> auth, null);
// decision.isGranted() == true
// Anonymous user
Authentication anonymous = new AnonymousAuthenticationToken(
"key",
"anonymous",
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")
);
AuthorizationDecision denied = manager.check(() -> anonymous, null);
// denied.isGranted() == false (anonymous is not considered authenticated)Checks if the authentication has all of the specified authorities.
package org.springframework.security.authorization;
class AllAuthoritiesAuthorizationManager implements AuthorizationManager<Object> {
AllAuthoritiesAuthorizationManager();
void setAuthority(String authority);
void setAuthorities(String... authorities);
void setAuthorities(Collection<String> authorities);
@Nullable AuthorizationDecision check(
Supplier<Authentication> authentication,
Object object);
}Key Methods:
Same as AuthorityAuthorizationManager but with different behavior.
Behavior:
Example:
AllAuthoritiesAuthorizationManager manager = new AllAuthoritiesAuthorizationManager();
manager.setAuthorities("ROLE_ADMIN", "ROLE_FINANCE");
// User with both authorities
Authentication fullAuth = new UsernamePasswordAuthenticationToken(
"admin",
"password",
AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_FINANCE", "ROLE_USER")
);
AuthorizationDecision granted = manager.check(() -> fullAuth, null);
// granted.isGranted() == true (has both ROLE_ADMIN and ROLE_FINANCE)
// User with only one authority
Authentication partialAuth = new UsernamePasswordAuthenticationToken(
"user",
"password",
AuthorityUtils.createAuthorityList("ROLE_ADMIN")
);
AuthorizationDecision denied = manager.check(() -> partialAuth, null);
// denied.isGranted() == false (missing ROLE_FINANCE)Checks if the authentication has all required authentication factors.
package org.springframework.security.authorization;
class AllRequiredFactorsAuthorizationManager implements AuthorizationManager<Object> {
AllRequiredFactorsAuthorizationManager();
void setFactor(String factor);
void setFactors(String... factors);
void setFactors(Collection<String> factors);
@Nullable AuthorizationDecision check(
Supplier<Authentication> authentication,
Object object);
}Key Methods:
void setFactor(String factor)void setFactors(String... factors)void setFactors(Collection<String> factors)Behavior:
FactorGrantedAuthority instances in the authentication.Example:
import org.springframework.security.core.authority.FactorGrantedAuthority;
AllRequiredFactorsAuthorizationManager manager = new AllRequiredFactorsAuthorizationManager();
manager.setFactors("PASSWORD", "OTP");
// User with both factors
Collection<GrantedAuthority> factors = Arrays.asList(
FactorGrantedAuthority.fromFactor("PASSWORD"),
FactorGrantedAuthority.fromFactor("OTP"),
new SimpleGrantedAuthority("ROLE_USER")
);
Authentication mfaAuth = new UsernamePasswordAuthenticationToken(
"user",
"password",
factors
);
AuthorizationDecision granted = manager.check(() -> mfaAuth, null);
// granted.isGranted() == true (has both PASSWORD and OTP factors)
// User with only one factor
Collection<GrantedAuthority> singleFactor = Arrays.asList(
FactorGrantedAuthority.fromFactor("PASSWORD"),
new SimpleGrantedAuthority("ROLE_USER")
);
Authentication partialMfa = new UsernamePasswordAuthenticationToken(
"user",
"password",
singleFactor
);
AuthorizationDecision denied = manager.check(() -> partialMfa, null);
// denied.isGranted() == false (missing OTP factor)Represents a required authentication factor for authorization.
package org.springframework.security.authorization;
class RequiredFactor {
RequiredFactor(String factor);
String getFactor();
boolean equals(Object obj);
int hashCode();
String toString();
}Constructor:
RequiredFactor(String factor)Key Methods:
String getFactor()Example:
RequiredFactor passwordFactor = new RequiredFactor("PASSWORD");
RequiredFactor otpFactor = new RequiredFactor("OTP");
// Use with AllRequiredFactorsAuthorizationManager
AllRequiredFactorsAuthorizationManager manager = new AllRequiredFactorsAuthorizationManager();
manager.setFactors(
passwordFactor.getFactor(),
otpFactor.getFactor()
);Utility class providing static methods for combining multiple authorization managers.
package org.springframework.security.authorization;
class AuthorizationManagers {
static <T> AuthorizationManager<T> anyOf(
AuthorizationManager<T>... managers);
static <T> AuthorizationManager<T> allOf(
AuthorizationManager<T>... managers);
static <T> AuthorizationManager<T> anyOf(
List<AuthorizationManager<T>> managers);
static <T> AuthorizationManager<T> allOf(
List<AuthorizationManager<T>> managers);
}Static Methods:
static <T> AuthorizationManager<T> anyOf(
AuthorizationManager<T>... managers)static <T> AuthorizationManager<T> allOf(
AuthorizationManager<T>... managers)Example:
// anyOf: User needs ROLE_ADMIN OR ROLE_STAFF
AuthorityAuthorizationManager adminManager = new AuthorityAuthorizationManager();
adminManager.setAuthority("ROLE_ADMIN");
AuthorityAuthorizationManager staffManager = new AuthorityAuthorizationManager();
staffManager.setAuthority("ROLE_STAFF");
AuthorizationManager<Object> anyManager = AuthorizationManagers.anyOf(
adminManager,
staffManager
);
// User with ROLE_ADMIN
Authentication adminAuth = new UsernamePasswordAuthenticationToken(
"admin",
"password",
AuthorityUtils.createAuthorityList("ROLE_ADMIN")
);
AuthorizationDecision decision = anyManager.check(() -> adminAuth, null);
// decision.isGranted() == true
// User with ROLE_STAFF
Authentication staffAuth = new UsernamePasswordAuthenticationToken(
"staff",
"password",
AuthorityUtils.createAuthorityList("ROLE_STAFF")
);
AuthorizationDecision decision2 = anyManager.check(() -> staffAuth, null);
// decision2.isGranted() == true
// User with neither
Authentication userAuth = new UsernamePasswordAuthenticationToken(
"user",
"password",
AuthorityUtils.createAuthorityList("ROLE_USER")
);
AuthorizationDecision denied = anyManager.check(() -> userAuth, null);
// denied.isGranted() == falseallOf Example:
// allOf: User must be authenticated AND have ROLE_ADMIN
AuthenticatedAuthorizationManager authenticatedManager =
new AuthenticatedAuthorizationManager();
AuthorityAuthorizationManager adminManager = new AuthorityAuthorizationManager();
adminManager.setAuthority("ROLE_ADMIN");
AuthorizationManager<Object> combinedManager = AuthorizationManagers.allOf(
authenticatedManager,
adminManager
);
// Authenticated admin user
Authentication adminAuth = new UsernamePasswordAuthenticationToken(
"admin",
"password",
AuthorityUtils.createAuthorityList("ROLE_ADMIN")
);
adminAuth.setAuthenticated(true);
AuthorizationDecision granted = combinedManager.check(() -> adminAuth, null);
// granted.isGranted() == true (authenticated AND has ROLE_ADMIN)
// Unauthenticated user
Authentication unauthenticated = new UsernamePasswordAuthenticationToken(
"user",
"password",
AuthorityUtils.createAuthorityList("ROLE_ADMIN")
);
unauthenticated.setAuthenticated(false);
AuthorizationDecision denied = combinedManager.check(() -> unauthenticated, null);
// denied.isGranted() == false (not authenticated)Complex Combination:
// Complex: (ROLE_ADMIN OR ROLE_STAFF) AND authenticated
AuthorityAuthorizationManager adminOrStaff = AuthorizationManagers.anyOf(
new AuthorityAuthorizationManager() {{ setAuthority("ROLE_ADMIN"); }},
new AuthorityAuthorizationManager() {{ setAuthority("ROLE_STAFF"); }}
);
AuthorizationManager<Object> finalManager = AuthorizationManagers.allOf(
new AuthenticatedAuthorizationManager(),
adminOrStaff
);Wraps an AuthorizationManager with Micrometer observation support for metrics and tracing.
package org.springframework.security.authorization;
class ObservationAuthorizationManager<T> implements AuthorizationManager<T> {
ObservationAuthorizationManager(
AuthorizationManager<T> delegate,
ObservationRegistry observationRegistry);
@Nullable AuthorizationDecision check(
Supplier<Authentication> authentication,
T object);
}Constructor:
ObservationAuthorizationManager(
AuthorizationManager<T> delegate,
ObservationRegistry observationRegistry)Behavior:
Example:
import io.micrometer.observation.ObservationRegistry;
AuthorityAuthorizationManager delegate = new AuthorityAuthorizationManager();
delegate.setAuthority("ROLE_ADMIN");
ObservationRegistry registry = ObservationRegistry.create();
AuthorizationManager<Object> observedManager =
new ObservationAuthorizationManager<>(delegate, registry);
// Use as normal - observations are recorded automatically
Authentication auth = ...;
AuthorizationDecision decision = observedManager.check(() -> auth, null);Utility class for combining reactive authorization managers.
package org.springframework.security.authorization;
class ReactiveAuthorizationManagers {
static <T> ReactiveAuthorizationManager<T> anyOf(
ReactiveAuthorizationManager<T>... managers);
static <T> ReactiveAuthorizationManager<T> allOf(
ReactiveAuthorizationManager<T>... managers);
}Example:
ReactiveAuthorizationManager<RequestAuthorizationContext> adminManager = ...;
ReactiveAuthorizationManager<RequestAuthorizationContext> staffManager = ...;
ReactiveAuthorizationManager<RequestAuthorizationContext> anyManager =
ReactiveAuthorizationManagers.anyOf(adminManager, staffManager);
Mono<Authentication> auth = ...;
Mono<AuthorizationDecision> decision = anyManager.check(auth, context);@Configuration
public class AuthorizationConfiguration {
@Bean
public AuthorizationManager<RequestAuthorizationContext> adminOnly() {
AuthorityAuthorizationManager manager = new AuthorityAuthorizationManager();
manager.setAuthority("ROLE_ADMIN");
return manager;
}
@Bean
public AuthorizationManager<RequestAuthorizationContext> authenticatedAdmin() {
AuthenticatedAuthorizationManager authenticated = new AuthenticatedAuthorizationManager();
AuthorityAuthorizationManager admin = new AuthorityAuthorizationManager();
admin.setAuthority("ROLE_ADMIN");
return AuthorizationManagers.allOf(authenticated, admin);
}
@Bean
public AuthorizationManager<RequestAuthorizationContext> multiFactorAccess() {
AllRequiredFactorsAuthorizationManager manager =
new AllRequiredFactorsAuthorizationManager();
manager.setFactors("PASSWORD", "OTP");
return manager;
}
@Bean
public AuthorizationManager<RequestAuthorizationContext> adminOrStaff() {
AuthorityAuthorizationManager admin = new AuthorityAuthorizationManager();
admin.setAuthority("ROLE_ADMIN");
AuthorityAuthorizationManager staff = new AuthorityAuthorizationManager();
staff.setAuthority("ROLE_STAFF");
return AuthorizationManagers.anyOf(admin, staff);
}
@Bean
public AuthorizationManager<RequestAuthorizationContext> observedManager(
ObservationRegistry registry) {
AuthorityAuthorizationManager delegate = new AuthorityAuthorizationManager();
delegate.setAuthority("ROLE_ADMIN");
return new ObservationAuthorizationManager<>(delegate, registry);
}
}org.springframework.security.authorization