Core authentication and authorization framework for Spring applications with comprehensive user management and security context handling
Authority and role management in Spring Security provides the foundation for authorization decisions. This comprehensive system includes granted authority implementations, mapping strategies, and hierarchical role support.
Core Capabilities:
GrantedAuthority interface represents an authority (single method: getAuthority())SimpleGrantedAuthority - Basic string-based authority implementationFactorGrantedAuthority - Authority for multi-factor authentication with time-based trackingGrantedAuthoritiesMapper for transforming authoritiesRoleHierarchy for hierarchical role relationshipsAuthorityUtils for creating and managing authoritiesKey Interfaces and Classes:
GrantedAuthority - Interface: getAuthority() returns StringSimpleGrantedAuthority - Basic implementation (constructor takes String)FactorGrantedAuthority - MFA authority with getIssuedAt() timestampGrantedAuthoritiesMapper - Maps authorities from one set to anotherRoleHierarchy - Defines hierarchical role relationshipsRoleHierarchyImpl - Implementation with builder pattern and string-based configurationAuthorityUtils - Utility class: createAuthorityList(), authorityListToSet(), commaSeparatedStringToAuthorityList()Default Behaviors:
SimpleGrantedAuthority stores authority as String (no validation)FactorGrantedAuthority has standard factor constants (PASSWORD, OTT, WEBAUTHN, etc.)AuthorityUtils.createAuthorityList() creates SimpleGrantedAuthority instancesgetReachableGrantedAuthorities() returns input authorities plus implied onesNullAuthoritiesMapper returns authorities unchanged (no-op)NullRoleHierarchy returns authorities unchanged (no hierarchy)Threading Model:
Lifecycle:
Authentication.getAuthorities()Exceptions:
CycleInRoleHierarchyException - Thrown when cycle detected in role hierarchy configurationEdge Cases:
getAuthority() should not return null (but implementations may allow it)setRolePrefix())getIssuedAt() returns Instant (may be null for some factors)equals() / hashCode() (typically based on authority string)Represents an authority granted to an authentication object.
package org.springframework.security.core;
interface GrantedAuthority extends Serializable {
@Nullable String getAuthority();
}Key Methods:
String getAuthority()Usage:
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN");
String authString = authority.getAuthority(); // "ROLE_ADMIN"Container interface for objects that hold granted authorities.
package org.springframework.security.core.authority;
interface GrantedAuthoritiesContainer extends Serializable {
Collection<? extends GrantedAuthority> getGrantedAuthorities();
}Key Methods:
Collection<? extends GrantedAuthority> getGrantedAuthorities()Basic implementation of GrantedAuthority using a string representation.
package org.springframework.security.core.authority;
final class SimpleGrantedAuthority implements GrantedAuthority {
SimpleGrantedAuthority(String role);
@Nullable String getAuthority();
boolean equals(Object obj);
int hashCode();
String toString();
}Constructor:
SimpleGrantedAuthority(String role)Example:
GrantedAuthority adminAuth = new SimpleGrantedAuthority("ROLE_ADMIN");
GrantedAuthority userAuth = new SimpleGrantedAuthority("ROLE_USER");
GrantedAuthority readAuth = new SimpleGrantedAuthority("READ_PRIVILEGE");A GrantedAuthority specifically used for indicating the factor used at time of authentication. Supports time-based multi-factor authentication with issued-at tracking.
package org.springframework.security.core.authority;
final class FactorGrantedAuthority implements GrantedAuthority {
// Standard factor authority constants
public static final String AUTHORIZATION_CODE_AUTHORITY = "FACTOR_AUTHORIZATION_CODE";
public static final String BEARER_AUTHORITY = "FACTOR_BEARER";
public static final String CAS_AUTHORITY = "FACTOR_CAS";
public static final String OTT_AUTHORITY = "FACTOR_OTT";
public static final String PASSWORD_AUTHORITY = "FACTOR_PASSWORD";
public static final String SAML_RESPONSE_AUTHORITY = "FACTOR_SAML_RESPONSE";
public static final String WEBAUTHN_AUTHORITY = "FACTOR_WEBAUTHN";
public static final String X509_AUTHORITY = "FACTOR_X509";
// Factory methods
public static Builder withAuthority(String authority);
public static Builder withFactor(String factor);
public static FactorGrantedAuthority fromAuthority(String authority);
public static FactorGrantedAuthority fromFactor(String factor);
// Instance methods
String getAuthority();
Instant getIssuedAt();
// Builder
public static final class Builder {
Builder issuedAt(Instant issuedAt);
FactorGrantedAuthority build();
}
}Standard Factor Constants:
The class provides 8 standard factor authority constants for common authentication mechanisms:
AUTHORIZATION_CODE_AUTHORITY - OAuth2 Authorization CodeBEARER_AUTHORITY - Bearer token authenticationCAS_AUTHORITY - CAS authenticationOTT_AUTHORITY - One-time tokenPASSWORD_AUTHORITY - Password authenticationSAML_RESPONSE_AUTHORITY - SAML authenticationWEBAUTHN_AUTHORITY - WebAuthn authenticationX509_AUTHORITY - X.509 certificate authenticationFactory Methods:
withAuthority(String) - Creates a builder with the specified authoritywithFactor(String) - Creates a builder with "FACTOR_" prefix automatically addedfromAuthority(String) - Shortcut for withAuthority(authority).build()fromFactor(String) - Shortcut for withFactor(factor).build()Instance Methods:
getAuthority() - Returns the authority string (e.g., "FACTOR_PASSWORD")getIssuedAt() - Returns the instant when this authority was issuedUsage Examples:
import org.springframework.security.core.authority.FactorGrantedAuthority;
import java.time.Instant;
// Using standard factor constants
FactorGrantedAuthority passwordAuth =
FactorGrantedAuthority.fromAuthority(FactorGrantedAuthority.PASSWORD_AUTHORITY);
FactorGrantedAuthority ottAuth =
FactorGrantedAuthority.fromAuthority(FactorGrantedAuthority.OTT_AUTHORITY);
// Using custom factor with automatic "FACTOR_" prefix
FactorGrantedAuthority smsAuth = FactorGrantedAuthority.fromFactor("SMS");
// Results in authority: "FACTOR_SMS"
// Building with custom issued-at time
FactorGrantedAuthority webauthnAuth = FactorGrantedAuthority
.withAuthority(FactorGrantedAuthority.WEBAUTHN_AUTHORITY)
.issuedAt(Instant.now())
.build();
// Checking for specific factor in authentication
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
boolean hasPasswordFactor = auth.getAuthorities().stream()
.anyMatch(authority ->
FactorGrantedAuthority.PASSWORD_AUTHORITY.equals(authority.getAuthority()));
// Getting issued-at time from factor authority
auth.getAuthorities().stream()
.filter(a -> a instanceof FactorGrantedAuthority)
.map(a -> (FactorGrantedAuthority) a)
.forEach(factor -> {
System.out.println("Factor: " + factor.getAuthority() +
", Issued: " + factor.getIssuedAt());
});Utility class for creating and managing granted authorities.
package org.springframework.security.core.authority;
class AuthorityUtils {
static final List<GrantedAuthority> NO_AUTHORITIES;
static List<GrantedAuthority> createAuthorityList(String... authorities);
static Set<String> authorityListToSet(
Collection<? extends GrantedAuthority> authorities);
static List<GrantedAuthority> commaSeparatedStringToAuthorityList(
String authorityString);
}Constants:
static final List<GrantedAuthority> NO_AUTHORITIESStatic Methods:
static List<GrantedAuthority> createAuthorityList(String... authorities)SimpleGrantedAuthority objects from string values.static Set<String> authorityListToSet(
Collection<? extends GrantedAuthority> authorities)static List<GrantedAuthority> commaSeparatedStringToAuthorityList(
String authorityString)Examples:
// Create authority list
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(
"ROLE_ADMIN",
"ROLE_USER",
"READ_PRIVILEGE"
);
// Convert to set of strings
Set<String> authorityStrings = AuthorityUtils.authorityListToSet(authorities);
// Returns: ["ROLE_ADMIN", "ROLE_USER", "READ_PRIVILEGE"]
// Parse comma-separated string
List<GrantedAuthority> parsed =
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN,ROLE_USER");
// Empty authorities
List<GrantedAuthority> none = AuthorityUtils.NO_AUTHORITIES;Interface for mapping granted authorities from one set to another, useful for transforming authorities from external systems.
package org.springframework.security.core.authority.mapping;
interface GrantedAuthoritiesMapper {
Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities);
}Key Methods:
Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities)No-operation mapper that returns the input authorities unchanged.
package org.springframework.security.core.authority.mapping;
class NullAuthoritiesMapper implements GrantedAuthoritiesMapper {
NullAuthoritiesMapper();
Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities);
}Usage:
GrantedAuthoritiesMapper mapper = new NullAuthoritiesMapper();
Collection<GrantedAuthority> mapped = mapper.mapAuthorities(originalAuthorities);
// mapped == originalAuthoritiesMaps authorities with configurable prefix and case conversion.
package org.springframework.security.core.authority.mapping;
class SimpleAuthorityMapper implements GrantedAuthoritiesMapper {
SimpleAuthorityMapper();
void setPrefix(String prefix);
void setConvertToUpperCase(boolean convertToUpperCase);
void setConvertToLowerCase(boolean convertToLowerCase);
void setDefaultAuthority(String defaultAuthority);
Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities);
}Key Methods:
void setPrefix(String prefix)void setConvertToUpperCase(boolean convertToUpperCase)void setConvertToLowerCase(boolean convertToLowerCase)void setDefaultAuthority(String defaultAuthority)Example:
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
mapper.setPrefix("ROLE_");
mapper.setConvertToUpperCase(true);
mapper.setDefaultAuthority("ROLE_USER");
// Input: ["admin", "user"]
Collection<GrantedAuthority> input = AuthorityUtils.createAuthorityList("admin", "user");
Collection<? extends GrantedAuthority> output = mapper.mapAuthorities(input);
// Output: ["ROLE_ADMIN", "ROLE_USER"]
// With empty input
Collection<? extends GrantedAuthority> defaulted =
mapper.mapAuthorities(Collections.emptyList());
// Output: ["ROLE_USER"]Interface for mapping attribute strings to granted authorities.
package org.springframework.security.core.authority.mapping;
interface Attributes2GrantedAuthoritiesMapper {
List<GrantedAuthority> getGrantedAuthorities(Collection<String> attributes);
}Key Methods:
List<GrantedAuthority> getGrantedAuthorities(Collection<String> attributes)Simple implementation with prefix and case conversion support.
package org.springframework.security.core.authority.mapping;
class SimpleAttributes2GrantedAuthoritiesMapper
implements Attributes2GrantedAuthoritiesMapper {
SimpleAttributes2GrantedAuthoritiesMapper();
void setAttributePrefix(String attributePrefix);
void setConvertAttributeToUpperCase(boolean convertAttributeToUpperCase);
void setConvertAttributeToLowerCase(boolean convertAttributeToLowerCase);
void setAddPrefixIfAlreadyExisting(boolean addPrefixIfAlreadyExisting);
List<GrantedAuthority> getGrantedAuthorities(Collection<String> attributes);
}Key Methods:
void setAttributePrefix(String attributePrefix)void setConvertAttributeToUpperCase(boolean convertAttributeToUpperCase)void setConvertAttributeToLowerCase(boolean convertAttributeToLowerCase)void setAddPrefixIfAlreadyExisting(boolean addPrefixIfAlreadyExisting)Example:
SimpleAttributes2GrantedAuthoritiesMapper mapper =
new SimpleAttributes2GrantedAuthoritiesMapper();
mapper.setAttributePrefix("ROLE_");
mapper.setConvertAttributeToUpperCase(true);
mapper.setAddPrefixIfAlreadyExisting(false);
List<String> attributes = Arrays.asList("admin", "user", "ROLE_guest");
List<GrantedAuthority> authorities = mapper.getGrantedAuthorities(attributes);
// Result: [ROLE_ADMIN, ROLE_USER, ROLE_GUEST]Maps attributes to authorities using a predefined map configuration.
package org.springframework.security.core.authority.mapping;
class MapBasedAttributes2GrantedAuthoritiesMapper
implements Attributes2GrantedAuthoritiesMapper {
MapBasedAttributes2GrantedAuthoritiesMapper();
void setAttributesToRoles(Map<String, Collection<String>> attributesToRoles);
List<GrantedAuthority> getGrantedAuthorities(Collection<String> attributes);
}Key Methods:
void setAttributesToRoles(Map<String, Collection<String>> attributesToRoles)Example:
MapBasedAttributes2GrantedAuthoritiesMapper mapper =
new MapBasedAttributes2GrantedAuthoritiesMapper();
Map<String, Collection<String>> mappings = new HashMap<>();
mappings.put("administrators", Arrays.asList("ROLE_ADMIN", "ROLE_USER"));
mappings.put("users", Collections.singletonList("ROLE_USER"));
mappings.put("guests", Collections.singletonList("ROLE_GUEST"));
mapper.setAttributesToRoles(mappings);
List<String> userAttributes = Arrays.asList("administrators");
List<GrantedAuthority> authorities = mapper.getGrantedAuthorities(userAttributes);
// Result: [ROLE_ADMIN, ROLE_USER]Interface for retrieving mappable attributes from a system.
package org.springframework.security.core.authority.mapping;
interface MappableAttributesRetriever {
Set<String> getMappableAttributes();
}Key Methods:
Set<String> getMappableAttributes()Simple implementation of mappable attributes retrieval.
package org.springframework.security.core.authority.mapping;
class SimpleMappableAttributesRetriever
implements MappableAttributesRetriever {
SimpleMappableAttributesRetriever();
void setMappableAttributes(Set<String> mappableAttributes);
Set<String> getMappableAttributes();
}Example:
SimpleMappableAttributesRetriever retriever =
new SimpleMappableAttributesRetriever();
retriever.setMappableAttributes(Set.of("admin", "user", "guest"));
Set<String> attributes = retriever.getMappableAttributes();
// Returns: ["admin", "user", "guest"]Defines hierarchical relationships between roles, where higher roles implicitly include permissions of lower roles.
package org.springframework.security.access.hierarchicalroles;
interface RoleHierarchy {
Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(
Collection<? extends GrantedAuthority> authorities);
}Key Methods:
Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(
Collection<? extends GrantedAuthority> authorities)Standard implementation of role hierarchy.
package org.springframework.security.access.hierarchicalroles;
class RoleHierarchyImpl implements RoleHierarchy {
RoleHierarchyImpl();
static RoleHierarchyImpl fromHierarchy(String hierarchyRepresentation);
static RoleHierarchyImpl withDefaultRolePrefix();
static RoleHierarchyImpl withRolePrefix(String rolePrefix);
void setHierarchy(String roleHierarchyStringRepresentation);
Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(
Collection<? extends GrantedAuthority> authorities);
}Static Factory Methods:
static RoleHierarchyImpl fromHierarchy(String hierarchyRepresentation)static RoleHierarchyImpl withDefaultRolePrefix()static RoleHierarchyImpl withRolePrefix(String rolePrefix)Key Methods:
void setHierarchy(String roleHierarchyStringRepresentation)String Format Examples:
// Format: ROLE_A > ROLE_B means ROLE_A includes ROLE_B
String hierarchy = """
ROLE_ADMIN > ROLE_STAFF
ROLE_STAFF > ROLE_USER
ROLE_USER > ROLE_GUEST
""";
RoleHierarchyImpl roleHierarchy = RoleHierarchyImpl.fromHierarchy(hierarchy);Builder Example:
RoleHierarchyImpl hierarchy = RoleHierarchyImpl.withDefaultRolePrefix()
.role("ADMIN").implies("STAFF")
.role("STAFF").implies("USER")
.role("USER").implies("GUEST")
.build();
// Test the hierarchy
Collection<GrantedAuthority> adminAuth =
AuthorityUtils.createAuthorityList("ROLE_ADMIN");
Collection<? extends GrantedAuthority> reachable =
hierarchy.getReachableGrantedAuthorities(adminAuth);
// Returns: [ROLE_ADMIN, ROLE_STAFF, ROLE_USER, ROLE_GUEST]Advanced Configuration:
// Multiple inheritance
String complexHierarchy = """
ROLE_ADMIN > ROLE_USER
ROLE_ADMIN > ROLE_STAFF
ROLE_STAFF > ROLE_EMPLOYEE
ROLE_USER > ROLE_GUEST
""";
RoleHierarchyImpl hierarchy = RoleHierarchyImpl.fromHierarchy(complexHierarchy);
Collection<GrantedAuthority> adminRole =
AuthorityUtils.createAuthorityList("ROLE_ADMIN");
Collection<? extends GrantedAuthority> all =
hierarchy.getReachableGrantedAuthorities(adminRole);
// Returns: [ROLE_ADMIN, ROLE_USER, ROLE_STAFF, ROLE_EMPLOYEE, ROLE_GUEST]No-operation role hierarchy that returns authorities unchanged.
package org.springframework.security.access.hierarchicalroles;
class NullRoleHierarchy implements RoleHierarchy {
NullRoleHierarchy();
Collection<? extends GrantedAuthority> getReachableGrantedAuthorities(
Collection<? extends GrantedAuthority> authorities);
}Usage:
RoleHierarchy noHierarchy = new NullRoleHierarchy();
Collection<? extends GrantedAuthority> same =
noHierarchy.getReachableGrantedAuthorities(authorities);
// Returns the input authorities unchangedGranted authorities mapper that applies role hierarchy during mapping.
package org.springframework.security.access.hierarchicalroles;
class RoleHierarchyAuthoritiesMapper implements GrantedAuthoritiesMapper {
RoleHierarchyAuthoritiesMapper(RoleHierarchy roleHierarchy);
Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities);
}Constructor:
RoleHierarchyAuthoritiesMapper(RoleHierarchy roleHierarchy)Example:
RoleHierarchyImpl hierarchy = RoleHierarchyImpl.withDefaultRolePrefix()
.role("ADMIN").implies("USER")
.build();
RoleHierarchyAuthoritiesMapper mapper =
new RoleHierarchyAuthoritiesMapper(hierarchy);
Collection<GrantedAuthority> authorities =
AuthorityUtils.createAuthorityList("ROLE_ADMIN");
Collection<? extends GrantedAuthority> expanded =
mapper.mapAuthorities(authorities);
// Returns: [ROLE_ADMIN, ROLE_USER]Utility methods for working with role hierarchies.
package org.springframework.security.access.hierarchicalroles;
class RoleHierarchyUtils {
static String roleHierarchyFromMap(Map<String, List<String>> roleHierarchyMap);
}Static Methods:
static String roleHierarchyFromMap(Map<String, List<String>> roleHierarchyMap)Example:
Map<String, List<String>> hierarchyMap = new HashMap<>();
hierarchyMap.put("ROLE_ADMIN", Arrays.asList("ROLE_STAFF", "ROLE_USER"));
hierarchyMap.put("ROLE_STAFF", Collections.singletonList("ROLE_USER"));
hierarchyMap.put("ROLE_USER", Collections.singletonList("ROLE_GUEST"));
String hierarchyString = RoleHierarchyUtils.roleHierarchyFromMap(hierarchyMap);
// Result:
// ROLE_ADMIN > ROLE_STAFF
// ROLE_ADMIN > ROLE_USER
// ROLE_STAFF > ROLE_USER
// ROLE_USER > ROLE_GUEST
RoleHierarchyImpl hierarchy = RoleHierarchyImpl.fromHierarchy(hierarchyString);Exception thrown when a cycle is detected in the role hierarchy configuration.
package org.springframework.security.access.hierarchicalroles;
class CycleInRoleHierarchyException extends RuntimeException {
CycleInRoleHierarchyException(String message);
CycleInRoleHierarchyException(String message, Throwable cause);
}Example:
try {
// This creates a cycle: ADMIN > USER > STAFF > ADMIN
String cyclicHierarchy = """
ROLE_ADMIN > ROLE_USER
ROLE_USER > ROLE_STAFF
ROLE_STAFF > ROLE_ADMIN
""";
RoleHierarchyImpl hierarchy = RoleHierarchyImpl.fromHierarchy(cyclicHierarchy);
} catch (CycleInRoleHierarchyException e) {
// Handle cyclic hierarchy error
}@Configuration
public class AuthorityConfiguration {
@Bean
public RoleHierarchy roleHierarchy() {
return RoleHierarchyImpl.withDefaultRolePrefix()
.role("ADMIN").implies("STAFF")
.role("ADMIN").implies("USER")
.role("STAFF").implies("USER")
.role("USER").implies("GUEST")
.build();
}
@Bean
public GrantedAuthoritiesMapper authoritiesMapper() {
SimpleAuthorityMapper mapper = new SimpleAuthorityMapper();
mapper.setPrefix("ROLE_");
mapper.setConvertToUpperCase(true);
mapper.setDefaultAuthority("ROLE_USER");
return mapper;
}
@Bean
public Attributes2GrantedAuthoritiesMapper attributeMapper() {
MapBasedAttributes2GrantedAuthoritiesMapper mapper =
new MapBasedAttributes2GrantedAuthoritiesMapper();
Map<String, Collection<String>> mappings = new HashMap<>();
mappings.put("admin", Arrays.asList("ROLE_ADMIN"));
mappings.put("staff", Arrays.asList("ROLE_STAFF"));
mappings.put("user", Arrays.asList("ROLE_USER"));
mapper.setAttributesToRoles(mappings);
return mapper;
}
}
// Usage in custom authentication provider
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final GrantedAuthoritiesMapper authoritiesMapper;
private final RoleHierarchy roleHierarchy;
@Override
public Authentication authenticate(Authentication authentication) {
// Authenticate user and get base authorities
Collection<GrantedAuthority> baseAuthorities =
loadUserAuthorities(authentication.getName());
// Map authorities
Collection<? extends GrantedAuthority> mappedAuthorities =
authoritiesMapper.mapAuthorities(baseAuthorities);
// Apply role hierarchy
Collection<? extends GrantedAuthority> finalAuthorities =
roleHierarchy.getReachableGrantedAuthorities(mappedAuthorities);
return new UsernamePasswordAuthenticationToken(
authentication.getPrincipal(),
authentication.getCredentials(),
finalAuthorities
);
}
}org.springframework.security.core.authorityorg.springframework.security.core.authority.mappingorg.springframework.security.access.hierarchicalrolesInstall with Tessl CLI
npx tessl i tessl/maven-spring-security-coredocs