ArchitectMind
  1. Home
  2. Tutorials
  3. Book 4 · Spring & Spring Boot
  4. Volume VI
  5. Security Architecture
Book 4 · Volume VI — Spring Security, OAuth2 & Identity · Topic 1.1

Security Architecture

Authentication, authorization, principal and SecurityContext

7 min readStage 2 · Frameworks & design8 interview questions
Chapter
Chapter 1 — Spring Security Fundamentals
Prerequisites
Volume IV (Spring MVC request lifecycle)
You will be able to
Explain Spring Security's core abstractions, distinguish authentication from authorisation, describe how principals and authorities are represented, and understand Boot's secure defaults
Covers
Authentication · Authorization · Principal · SecurityContext
On this page
  1. 1. Concept / Definition
  2. 2. Why It Exists
  3. 3. Core Concepts
  4. 4. How It Works Internally
  5. 4A. Deep Dive — Spring Boot's Secure Defaults and Explicit Configuration
  6. 5. APIs / Features / Syntax
  7. 6. Practical Examples
  8. 7. Common Problems & Mistakes
  9. 8. Performance & Production Considerations
  10. 9. Architecture & Design Considerations
  11. 10. Interview Questions & Answers

1Concept / Definition

Spring Security's architecture answers two questions for every protected operation: who is the caller? (authentication) and may the caller do this? (authorisation). The result of authentication — a principal with its authorities — is stored in the SecurityContext, which authorisation decisions read.

Spring Security architecture
Figure 1 — Spring Security architecture
ConceptSpring Security typeRole
AuthenticationAuthentication, AuthenticationManagerVerify credentials → authenticated Authentication
AuthorizationAuthorizationManager<T>Grant or deny access to a request, method or object
PrincipalAuthentication.getPrincipal() (e.g. UserDetails, Jwt, OidcUser)The identity
AuthoritiesCollection<? extends GrantedAuthority>Roles (ROLE_ADMIN), permissions, scopes (SCOPE_read)
SecurityContextSecurityContext, SecurityContextHolderHolds the current Authentication for the request
Table 1 — Core abstractions

2Why It Exists

Security logic scattered across controllers is inconsistent and easy to bypass. Spring Security (originally Acegi, 2004) centralised it in a framework: authentication mechanisms are pluggable providers, authorisation is declarative, and both run before application code in servlet filters and method interceptors. The result is defence that applies uniformly — including to endpoints developers forget — with secure defaults and hooks for every major protocol (form login, HTTP Basic, OAuth2, OIDC, SAML, LDAP, X.509, WebAuthn).

3Core Concepts

3.1 Authentication

Core security concepts
Figure 2 — Core security concepts
JAVA
public interface Authentication extends Principal, Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    Object getCredentials();        // password, token — erased after authentication
    Object getDetails();            // IP address, session id, …
    Object getPrincipal();          // UserDetails, Jwt, OidcUser, String
    boolean isAuthenticated();
}
MechanismAuthentication type
Form login / HTTP BasicUsernamePasswordAuthenticationToken
Bearer JWT (resource server)JwtAuthenticationToken
OAuth2/OIDC loginOAuth2AuthenticationToken
AnonymousAnonymousAuthenticationToken
Remember-me, X.509, pre-authenticatedSpecific token types
Table 2 — Authentication implementations

3.2 Authorization

Authorisation happens at several levels, all built on AuthorizationManager:

LevelConfiguration
HTTP requestshttp.authorizeHttpRequests(…)
Methods@EnableMethodSecurity + @PreAuthorize etc.
Objects/data@PostAuthorize, @AuthorizeReturnObject, domain checks
MessagesWebSocket/messaging security
Table 3 — Authorization levels

3.3 Principal

The principal is whatever represents the identity for the mechanism used: a UserDetails from a user store, a Jwt with claims, an OidcUser with ID token claims, or simply a username string. Authentication.getName() gives a uniform identifier (username, sub claim).

3.4 SecurityContext

Where Spring Security operates
Figure 3 — Where Spring Security operates

The SecurityContextHolder stores the SecurityContext for the current execution (thread-local by default in servlet apps). Any code in the request — filters, controllers, services, @PreAuthorize expressions — can read the current Authentication from it (Topic 1.3).

4How It Works Internally

1. Boot registers a DelegatingFilterProxy named springSecurityFilterChain in the servlet container; it delegates to the FilterChainProxy bean.

2. FilterChainProxy selects the first SecurityFilterChain matching the request and runs its filters (Topic 1.2).

3. An authentication filter extracts credentials, calls the AuthenticationManager, and on success stores the resulting Authentication in a new SecurityContext via the SecurityContextHolderStrategy (and optionally persists it via SecurityContextRepository).

4. The AuthorizationFilter asks the configured AuthorizationManager whether the current Authentication may access the request.

5. Failures raise AuthenticationException (→ 401 via entry point) or AccessDeniedException (→ 403 via access-denied handler), handled by ExceptionTranslationFilter.

6. At the end of the request, the context is cleared from the thread.

4ADeep Dive — Spring Boot's Secure Defaults and Explicit Configuration

Boot defaults with the security starter
Figure 4 — Boot defaults with the security starter
JAVA
@Configuration
@EnableWebSecurity
class SecurityConfig {
 
    @Bean
    SecurityFilterChain appSecurity(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/public/**", "/actuator/health/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated())
            .formLogin(Customizer.withDefaults())
            .logout(Customizer.withDefaults());
        return http.build();
    }
 
    @Bean
    UserDetailsService users(PasswordEncoder encoder) {                 // demo only
        return new InMemoryUserDetailsManager(
                User.withUsername("admin")
                    .password(encoder.encode("change-me"))
                    .roles("ADMIN")
                    .build());
    }
 
    @Bean
    PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
}
Boot defaultWhen it appliesHow to replace
Default SecurityFilterChain (all authenticated, form + Basic)No SecurityFilterChain bean definedDeclare your own bean
Generated user passwordNo UserDetailsService, AuthenticationProvider or OAuth2 configDefine a user store or OAuth2 resource server
CSRF protectionAlways, unless disabledConfigure per chain (Volume VI Ch. 7)
Security headersAlwayshttp.headers(...)
Table 4 — Boot's defaults and how they back off

5APIs / Features / Syntax

APIPurpose
spring-boot-starter-securitySpring Security + Boot auto-configuration
SecurityFilterChain bean + HttpSecurity lambda DSLWeb security configuration
Authentication, GrantedAuthority, SimpleGrantedAuthorityIdentity representation
AuthenticationManager, AuthenticationProviderAuthentication
AuthorizationManager, authorizeHttpRequests, @EnableMethodSecurityAuthorisation
SecurityContextHolder, SecurityContextHolderStrategyContext access
logging.level.org.springframework.securityDiagnostics
Table 5 — Core Spring Security APIs

6Practical Examples

6.1 Seeing the architecture in logs

TEXT
TRACE FilterChainProxy : Trying to match request against
      DefaultSecurityFilterChain [...] (1/1)
DEBUG FilterChainProxy : Securing GET /admin/reports
TRACE AuthorizationFilter : Authorizing GET /admin/reports
DEBUG ExceptionTranslationFilter : Sending AnonymousAuthenticationToken
      to authentication entry point since access is denied

6.2 Reading the current user in a controller

JAVA
@GetMapping("/me")
Map<String, Object> me(Authentication authentication) {
    return Map.of("name", authentication.getName(),
                  "authorities",
                  AuthorityUtils.authorityListToSet(authentication.getAuthorities()));
}

6.3 Testing a rule

JAVA
@WebMvcTest(AdminController.class)
@Import(SecurityConfig.class)
class AdminSecurityTest {
    @Autowired MockMvcTester mvc;
 
    @Test
    void anonymousIsRedirectedOrUnauthorized() {
        assertThat(mvc.get().uri("/admin/reports")).hasStatus3xxRedirection();
    }
 
    @Test
    @WithMockUser(roles = "USER")
    void userIsForbidden() {
        assertThat(mvc.get().uri("/admin/reports")).hasStatus(HttpStatus.FORBIDDEN);
    }
 
    @Test
    @WithMockUser(roles = "ADMIN")
    void adminIsAllowed() {
        assertThat(mvc.get().uri("/admin/reports")).hasStatusOk();
    }
}

6.4 401 vs 403

SituationStatusMeaning
No or invalid credentials401 UnauthorizedAuthenticate (again)
Valid credentials, insufficient rights403 ForbiddenAuthenticated but not allowed
Browser app, unauthenticated302 to login pageEntry point chooses redirect
Table 6 — Authentication vs authorisation failures

6.5 Security concerns and their Spring Security components

ConcernComponent
Credential verificationAuthenticationProviders
Identity storage per requestSecurityContextHolder
Session persistence of identitySecurityContextRepository
Access decisionsAuthorizationManager
Error responsesAuthenticationEntryPoint, AccessDeniedHandler
Browser protectionsCSRF, headers, CORS filters
Table 7 — Mapping concerns to components

7Common Problems & Mistakes

  • Mixing authentication and authorisation logic in controllers.
  • Relying on Boot's generated user beyond local development.
  • Returning 403 for unauthenticated calls (or 401 for forbidden ones) — confuses clients.
  • Checking roles by string comparison in business code instead of using authorities and method security.
  • Disabling security for "internal" endpoints that are reachable externally.
  • Logging credentials or tokens in debug output.

8Performance & Production Considerations

ConcernGuidance
Filter overheadNegligible except password hashing (by design) and remote token introspection
AuditingPublish and record authentication success/failure events
MonitoringRates of 401/403, login failures, lockouts
SecretsCredentials and signing keys from secret stores (Volume III)
Table 8 — Production guidance

9Architecture & Design Considerations

  • Centralised, declarative security — never ad-hoc checks in controllers.
  • Separation of identity (authentication) from access (authorisation) across components and teams.
  • Authorities as the contract between identity sources and application rules.
  • Security as a platform starter with standard chains, error formats and audit events.

10Interview Questions & Answers

Q1Basic

What is the difference between authentication and authorisation?

Authentication answers "who are you?": it verifies the caller's identity, for example by checking a password, validating a JWT issued by an identity provider or verifying a client certificate. Authorisation answers "what may you do?": it decides whether that authenticated identity is allowed to perform a specific action on a specific resource, such as approving a refund over a certain amount. Authentication normally happens once per request or session at the boundary; authorisation can happen many times, at URL level and on individual methods. A system can authenticate perfectly and still be insecure if its authorisation rules are missing or wrong.

Q2Basic

What does the Authentication object contain?

Spring Security's Authentication object represents a caller. It contains the principal, the identity, such as a UserDetails object, a Jwt or an OidcUser; the credentials, such as a password, which are usually erased after successful login so they do not linger in memory; the granted authorities, which are the roles and permissions used for authorisation decisions; optional details, such as the remote address and session ID; and a flag indicating whether it has been authenticated. After login it is stored in the SecurityContext, which is available to the rest of the request through SecurityContextHolder or method parameters.

Q3Intermediate

What is a principal?

The principal is the authenticated identity of the caller, the thing that was proven during authentication. Its type depends on how the user logged in: a UserDetails object for username and password login, a Jwt for a resource server receiving bearer tokens, an OidcUser for OpenID Connect login, or a custom type. Code can access it through Authentication.getPrincipal(), or more conveniently with @AuthenticationPrincipal in a controller method. The principal typically provides the user's identifier and attributes such as name or email, which are used for authorisation decisions, auditing and personalising responses.

Q4Intermediate

What does Spring Boot configure when you add the security starter?

Adding spring-boot-starter-security secures the application immediately. Boot configures a default security filter chain that requires authentication for every request, enables form login and HTTP Basic, and, if no other user source is configured, creates a single user named user with a random password printed in the log. It enables CSRF protection for state-changing requests, adds security headers such as X-Content-Type-Options and cache-control headers, and configures session management. These defaults are deliberately strict, so nothing is accidentally exposed, but almost every real application replaces them with its own SecurityFilterChain bean.

Q5Senior Engineer

What HTTP statuses correspond to authentication and authorisation failures?

A 401 Unauthorized response means the request lacks valid authentication: there are no credentials, the token has expired or the signature is invalid. Despite its name, it is about authentication, and it should include a WWW-Authenticate header telling the client how to authenticate. A 403 Forbidden response means the caller is authenticated, but is not allowed to perform this action, for example a customer trying to access an admin endpoint. In Spring Security, the AuthenticationEntryPoint produces the 401 and the AccessDeniedHandler produces the 403. Using them correctly helps clients decide whether to log in again or give up.

Q6Senior Engineer

What is AuthorizationManager?

AuthorizationManager is Spring Security's single abstraction for access decisions, introduced to replace the older AccessDecisionManager and voters. Given a supplier of the current Authentication and the object being secured, such as an HTTP request, a method invocation or a message, it returns an authorisation decision. The same model is used for URL rules configured with authorizeHttpRequests, for method security annotations such as @PreAuthorize, and for messaging security. Teams can write custom implementations, for example to check ownership of a resource or call an external policy engine, and reuse them consistently across all three levels.

Q7Technical Architect

Why should security be enforced in filters rather than controllers?

Spring Security's filters run in the servlet filter chain before any controller code, for every request that reaches the application. Enforcing security there means it is applied centrally and consistently: developers cannot forget to add a check to a new endpoint, and requests that fail authentication are rejected before they touch application code. URL-based rules in the filter chain give a secure default, such as denying anything not explicitly allowed. Method-level annotations on services then add fine-grained authorisation. Checks scattered inside controller methods are easy to miss, hard to audit and do not protect non-HTTP entry points.

Q8Solution Architect

How would you organise security responsibilities across an enterprise?

Split responsibilities by what each layer knows. Centralise authentication in an identity provider, using single sign-on with OpenID Connect for users and OAuth 2.0 client credentials or workload identity for services, so applications never handle passwords. Keep authorisation rules close to the domain services that own the data, because only they understand concepts such as account ownership or approval limits. Standardise security configuration through platform starters that set up token validation, headers and error responses consistently. Enforce coarse rules at the API gateway, audit authentication and authorisation decisions centrally, and review security architecture as part of every design review.

Newsletter

Get new tutorials every week

New ArchitectMind tutorials and interview questions, once a week. No spam, unsubscribe anytime.

Almost done! Check your inbox and click the confirmation link to complete your subscription.
Keep going in Book 4

Spring & Spring Boot

Volume I · Topic 1.1

Why Spring Exists

Spring Core, IoC & Dependency Injection

Volume I · Topic 1.2

Spring Framework Architecture

Spring Core, IoC & Dependency Injection

Volume I · Topic 1.3

Spring Modules

Spring Core, IoC & Dependency Injection

Volume II · Topic 1.1

Cross-Cutting Concerns

Spring AOP, Proxies, Events & Transactions

Volume II · Topic 1.2

Why Cross-Cutting Concerns Are Difficult

Spring AOP, Proxies, Events & Transactions

Volume II · Topic 1.3

Aspect-Oriented Programming

Spring AOP, Proxies, Events & Transactions

Volume III · Topic 1.1

Why Spring Boot Exists

Spring Boot, Configuration & Application Lifecycle

Volume III · Topic 1.2

Spring Boot Architecture

Spring Boot, Configuration & Application Lifecycle

Volume III · Topic 1.3

Spring Boot vs Spring Framework

Spring Boot, Configuration & Application Lifecycle

Volume IV · Topic 1.1

MVC

Spring MVC, REST & Web Applications

Volume IV · Topic 1.2

DispatcherServlet

Spring MVC, REST & Web Applications

Volume IV · Topic 1.3

MVC Request Lifecycle

Spring MVC, REST & Web Applications

Volume V · Topic 1.1

Repository Abstraction

Spring Data, JPA & Persistence

Volume V · Topic 1.2

Spring Data Architecture

Spring Data, JPA & Persistence

Volume V · Topic 1.3

Repository Types

Spring Data, JPA & Persistence

Volume VI · Topic 1.2

Security Filter Chain

Spring Security, OAuth2 & Identity

Volume VI · Topic 1.3

Security Context

Spring Security, OAuth2 & Identity

Volume VII · Topic 1.1

Enterprise Integration

Spring Integration, Testing & Cloud-Native Development

Volume VII · Topic 1.2

Integration Patterns

Spring Integration, Testing & Cloud-Native Development

Volume VII · Topic 1.3

Messaging Systems

Spring Integration, Testing & Cloud-Native Development