Week 6 Day 1 — Spring Security Mental Model
Goal
Today I want to understand the mental model of Spring Security.
Main questions:
- What problem does Spring Security solve?
- What is authentication?
- What is authorization?
- What is the difference between authentication and authorization?
- Why does Spring Security use filters?
- What is
SecurityFilterChain? - What is
FilterChainProxy? - What is
SecurityContextHolder? - What happens when I add
spring-boot-starter-security? - How do I customize security rules?
- What is
PasswordEncoder? - What are common exam traps?
1. Quick Review from Week 5
In Week 5, I learned:
- Controller handles HTTP.
- Service handles business logic and transactions.
- Repository handles persistence.
- Entity maps to database.
- DTO maps to API.
@Transactionaldefines transaction boundaries.- REST APIs should usually return DTOs, not entities.
Memory sentence:
Controller -> Service -> Repository -> Database
Now I add security in front of the controller.
Spring Security works before the request reaches my controller.
Memory sentence:
Security checks happen before controller logic.
2. What Problem Does Spring Security Solve?
Most applications need security.
Examples:
Who is the user?
Is the user logged in?
Is the password correct?
Can this user access this endpoint?
Can this user perform this action?
Should this request be blocked?
Should CSRF protection be applied?
Should a session be created?
Should a JWT token be accepted?
Spring Security helps with:
authentication
authorization
password encoding
security filters
login/logout
HTTP Basic
form login
CSRF protection
session management
method security
OAuth2 / JWT support
protection against common attacks
Simple definition:
Spring Security is the Spring framework for authentication, authorization, and common security protections.
Memory sentence:
Spring Security protects requests before they reach controllers.
3. Authentication
Authentication answers:
Who are you?
Examples:
username and password
session cookie
JWT token
OAuth2 login
API key
certificate
If authentication succeeds, Spring Security knows the current user.
Example:
User: steve@example.com
Roles: USER, ADMIN
Authenticated: true
Memory sentence:
Authentication means proving identity.
4. Authorization
Authorization answers:
What are you allowed to do?
Examples:
Can this user call GET /api/tasks?
Can this user delete a task?
Can this user access admin endpoints?
Can this user see another tenant's data?
Can this user approve an invoice?
Authorization happens after authentication.
Example:
Authenticated user: steve@example.com
Role: USER
Endpoint: DELETE /api/admin/users/10
Decision: denied
Memory sentence:
Authorization means checking permissions.
5. Authentication vs Authorization
| Concept | Question | Example |
|---|---|---|
| Authentication | Who are you? | Login with username/password |
| Authorization | What can you do? | Only ADMIN can delete users |
Memory:
Authentication = identity.
Authorization = permission.
Interview sentence:
Authentication happens first. Authorization decides whether the authenticated user may access something.
6. 401 vs 403
This is very important.
401 Unauthorized
Means:
You are not authenticated.
Examples:
missing token
invalid token
expired token
not logged in
403 Forbidden
Means:
You are authenticated, but you are not allowed.
Examples:
normal user tries to access admin endpoint
user tries to access another tenant's data
employee tries to approve a task without permission
Memory sentence:
401 = who are you?
403 = I know who you are, but you are not allowed.
7. Where Does Spring Security Sit?
Request flow without security:
Client -> DispatcherServlet -> Controller -> Service -> Repository
Request flow with security:
Client -> Spring Security Filters -> DispatcherServlet -> Controller -> Service -> Repository
Spring Security checks the request before Spring MVC controller logic.
Memory sentence:
Spring Security is in front of Spring MVC.
8. Why Filters?
In servlet web applications, filters can intercept HTTP requests before they reach the servlet.
Spring MVC uses:
DispatcherServlet
Spring Security uses:
Servlet filters
A filter can:
read request headers
check session
check token
authenticate user
reject request
allow request to continue
set security context
clear security context
Memory sentence:
Filters are perfect for security because they run before controllers.
9. Servlet Filter Chain
A request passes through a chain of filters.
Simple picture:
HTTP Request
↓
Filter 1
↓
Filter 2
↓
Filter 3
↓
DispatcherServlet
↓
Controller
Spring Security adds its own security filter chain.
Example security filters can handle:
CSRF
CORS
logout
username/password login
basic authentication
bearer token authentication
session management
authorization
exception handling
Memory sentence:
Spring Security is mainly filter-chain based.
10. What Is SecurityFilterChain?
SecurityFilterChain is the ordered set of security filters applied to matching HTTP requests.
Simple definition:
SecurityFilterChaindefines which security filters and security rules apply to requests.
In modern Spring Security, I usually define a bean:
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.build();
}
}
Meaning:
public endpoints are open
all other requests require authentication
HTTP Basic is enabled
Memory sentence:
SecurityFilterChainis where I configure web security rules.
11. HttpSecurity
HttpSecurity is the builder object used to configure servlet security.
Example:
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.build();
}
HttpSecurity configures things like:
authorization rules
login method
logout
CSRF
CORS
sessions
exception handling
headers
OAuth2 resource server
JWT
Memory sentence:
HttpSecuritybuilds theSecurityFilterChain.
12. What Is FilterChainProxy?
Spring Security has many filters.
But the servlet container usually sees one main Spring Security filter entry point.
Inside Spring Security, FilterChainProxy delegates to the right SecurityFilterChain.
Simple picture:
Servlet container
↓
DelegatingFilterProxy
↓
FilterChainProxy
↓
SecurityFilterChain
↓
Security filters
Simple definition:
FilterChainProxyis the Spring Security component that delegates requests to the matching security filter chain.
For daily coding, I usually configure SecurityFilterChain, not FilterChainProxy directly.
Memory sentence:
FilterChainProxyroutes requests through Spring Security filter chains.
13. Security Before DispatcherServlet
The request normally goes through security filters before reaching Spring MVC.
Flow:
1. HTTP request arrives.
2. Servlet container starts filter chain.
3. Spring Security filters run.
4. Authentication may happen.
5. Authorization decision is made.
6. If allowed, request continues.
7. DispatcherServlet receives request.
8. Controller method runs.
If request is denied:
controller method does not run
Memory sentence:
If Spring Security blocks the request, the controller is never called.
14. Default Security in Spring Boot
When I add:
implementation("org.springframework.boot:spring-boot-starter-security")
Spring Boot auto-configures basic security if I do not provide my own configuration.
Common default behavior in a web app:
all endpoints are secured
a generated password is printed in logs
a default user named user exists
form login may be available for browser requests
HTTP Basic may be available for API clients
This surprises many beginners.
Memory sentence:
Adding the security starter changes the whole application immediately.
15. Generated Password
After adding Spring Security, I may see a log like:
Using generated security password: ...
This is for development only.
Default username is commonly:
user
The generated password changes on restart.
In real apps, configure users properly.
Memory sentence:
The generated password is a development default, not production security.
16. First Security Config
Basic REST API security example:
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/actuator/health").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.build();
}
}
Meaning:
/api/auth/** is public
/actuator/health is public
everything else requires authentication
HTTP Basic is enabled
CSRF is disabled
Important:
Do not copy csrf.disable() blindly for every app.
For stateless APIs it is common.
For browser session apps, CSRF protection is important.
We will study CSRF later.
17. authorizeHttpRequests
authorizeHttpRequests configures authorization rules for HTTP requests.
Example:
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.GET, "/api/tasks/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
)
Meaning:
public endpoints are open
admin endpoints need ADMIN role
GET tasks need USER or ADMIN
everything else needs authentication
Memory sentence:
authorizeHttpRequestscontrols URL-based authorization.
18. Rule Order Matters
Security rules are checked in order.
Example:
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
Good.
But this is problematic:
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
)
Why?
anyRequest matches everything.
The admin rule after it becomes unreachable or invalid.
Memory sentence:
Put specific authorization rules before general rules.
19. Common Authorization Methods
Examples:
permitAll()
denyAll()
authenticated()
hasRole("ADMIN")
hasAnyRole("USER", "ADMIN")
hasAuthority("TASK_READ")
hasAnyAuthority("TASK_READ", "TASK_WRITE")
Meanings:
| Method | Meaning |
|---|---|
permitAll() | anyone can access |
denyAll() | nobody can access |
authenticated() | user must be authenticated |
hasRole("ADMIN") | user must have role ADMIN |
hasAuthority("TASK_READ") | user must have authority TASK_READ |
20. Role vs Authority
Spring Security works with authorities.
A role is usually represented as an authority with prefix:
ROLE_
Example:
hasRole("ADMIN")
checks for authority:
ROLE_ADMIN
Example:
hasAuthority("ROLE_ADMIN")
checks directly for:
ROLE_ADMIN
Important trap:
hasRole("ROLE_ADMIN")
Usually wrong, because hasRole adds the ROLE_ prefix.
Correct:
hasRole("ADMIN")
or:
hasAuthority("ROLE_ADMIN")
Memory sentence:
hasRole("ADMIN")means authorityROLE_ADMIN.
21. Authentication Object
After successful authentication, Spring Security stores authentication information.
Important concept:
Authentication
It usually contains:
principal
credentials
authorities
authenticated flag
details
Example:
principal = current user
credentials = password/token, usually cleared later
authorities = roles/permissions
authenticated = true
Memory sentence:
Authenticationrepresents the current authenticated user.
22. SecurityContext
SecurityContext holds the Authentication.
Simple picture:
SecurityContext
└── Authentication
├── principal
├── credentials
└── authorities
Memory sentence:
SecurityContextstores security information for the current request.
23. SecurityContextHolder
SecurityContextHolder stores the current SecurityContext.
Example:
Authentication authentication =
SecurityContextHolder.getContext().getAuthentication();
Then I can get:
String username = authentication.getName();
Collection<? extends GrantedAuthority> authorities =
authentication.getAuthorities();
Important:
Most application code should not manually use SecurityContextHolder everywhere.
Prefer method parameters or service abstractions when possible.
Memory sentence:
SecurityContextHoldergives access to the current security context.
24. Getting Current User in Controller
Example:
@GetMapping("/api/me")
public String me(Authentication authentication) {
return authentication.getName();
}
Spring can inject the current Authentication into controller methods.
Example with principal:
@GetMapping("/api/me")
public String me(Principal principal) {
return principal.getName();
}
Memory sentence:
Controllers can receive the current
AuthenticationorPrincipal.
25. SecurityContext Lifetime
For a normal request:
1. Security filter loads or creates SecurityContext.
2. Authentication is set after successful login/token check.
3. Controller/service can access current user.
4. At end of request, context is cleared.
Why clear it?
avoid leaking user information between requests/threads
Memory sentence:
Security context is request-related and must be cleared after request processing.
26. Authentication Flow: Username and Password
Simplified username/password flow:
1. User sends username and password.
2. Authentication filter extracts credentials.
3. AuthenticationManager tries to authenticate.
4. AuthenticationProvider checks user details and password.
5. If valid, Authentication is created.
6. SecurityContext stores Authentication.
7. Request is allowed if authorization passes.
Memory sentence:
AuthenticationManager authenticates credentials.
27. AuthenticationManager
Simple definition:
AuthenticationManageris responsible for authenticating an authentication request.
It receives an unauthenticated token, such as username/password.
Then it returns an authenticated Authentication or throws an exception.
Memory sentence:
AuthenticationManagerdecides whether credentials are valid.
28. AuthenticationProvider
AuthenticationProvider performs a specific authentication strategy.
Examples:
username/password against database
LDAP authentication
JWT token authentication
OAuth2 authentication
pre-authenticated user
For username/password, a common provider is:
DaoAuthenticationProvider
It uses:
UserDetailsService
PasswordEncoder
Memory sentence:
AuthenticationProvider knows how to authenticate one kind of credential.
29. UserDetailsService
UserDetailsService loads user information by username.
Typical method:
UserDetails loadUserByUsername(String username);
It returns:
username
encoded password
authorities
account status
Example:
@Service
public class DatabaseUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public DatabaseUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String email) {
UserEntity user = userRepository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException(email));
return User.builder()
.username(user.getEmail())
.password(user.getPasswordHash())
.roles(user.getRole())
.build();
}
}
Memory sentence:
UserDetailsServiceloads users for authentication.
30. PasswordEncoder
Never store raw passwords.
Bad:
password = "secret123"
Good:
password hash = "$2a$10$..."
PasswordEncoder handles password hashing and matching.
Example bean:
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
During registration:
String hash = passwordEncoder.encode(rawPassword);
During login:
passwordEncoder.matches(rawPassword, storedHash);
Memory sentence:
Store password hashes, not raw passwords.
31. Why Password Encoding Is One-Way
Password encoding is not encryption.
Encryption can be reversed with a key.
Password hashing should be one-way.
Meaning:
raw password -> hash
hash -> raw password should not be possible
At login, Spring compares:
raw password entered by user
stored password hash
using matches.
Memory sentence:
PasswordEncoder verifies passwords without decoding them.
32. In-Memory User Example
For learning:
@Configuration
public class SecurityConfig {
@Bean
UserDetailsService users(PasswordEncoder passwordEncoder) {
UserDetails user = User.builder()
.username("user@example.com")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin@example.com")
.password(passwordEncoder.encode("password"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
This is useful for demos and tests.
For real apps, users usually come from database, LDAP, OAuth2, or identity provider.
Memory sentence:
In-memory users are useful for learning, not real production user management.
33. Full Basic Security Config
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers(HttpMethod.GET, "/api/tasks/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.build();
}
@Bean
UserDetailsService users(PasswordEncoder passwordEncoder) {
UserDetails user = User.builder()
.username("user@example.com")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin@example.com")
.password(passwordEncoder.encode("password"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
This config:
opens /api/public/**
requires ADMIN for /api/admin/**
allows USER or ADMIN for GET /api/tasks/**
requires authentication for everything else
uses HTTP Basic
uses BCrypt password encoding
34. HTTP Basic
HTTP Basic sends credentials in the request header.
Example header:
Authorization: Basic base64(username:password)
Important:
Basic authentication must use HTTPS in real applications.
Why?
Base64 is not encryption.
Without HTTPS, credentials can be exposed.
Memory sentence:
HTTP Basic is simple but must be protected by HTTPS.
35. Form Login
Form login is common for browser-based applications.
Spring Security can generate or use a login page.
Flow:
1. User requests protected page.
2. User is redirected to login page.
3. User submits username/password.
4. Spring authenticates user.
5. SecurityContext is stored.
6. User continues with session cookie.
For REST APIs, form login is often not the desired behavior.
REST APIs often prefer:
HTTP Basic for simple internal APIs
JWT bearer tokens
OAuth2 resource server
session-based login if browser app
Memory sentence:
Form login is browser-oriented; APIs often use token or Basic authentication.
36. Session-Based Security
In session-based security:
server stores authentication in HTTP session
browser stores session cookie
cookie identifies session on future requests
Flow:
login once
server creates session
client sends session cookie
server loads security context from session
Good for:
traditional web apps
server-rendered apps
some browser apps
Memory sentence:
Session security stores login state on the server.
37. Stateless Token Security
In stateless token security:
client sends token on every request
server validates token
server does not need HTTP session for authentication
Example:
Authorization: Bearer eyJhbGciOi...
Common for:
REST APIs
mobile apps
single-page applications
microservices
We will study JWT/resource server later.
Memory sentence:
Stateless APIs authenticate each request using a token.
38. CSRF
CSRF means:
Cross-Site Request Forgery
It is mainly important for browser-based session authentication.
Simple idea:
A malicious site tricks the user's browser into sending a request to your site with the user's cookies.
Spring Security enables CSRF protection by default in many web scenarios.
For stateless REST APIs using bearer tokens, CSRF is often disabled.
Important:
Do not disable CSRF blindly.
Understand the authentication style first.
Memory sentence:
CSRF matters especially when browsers automatically send cookies.
39. CORS vs CSRF
CORS and CSRF are different.
CORS
Question:
Which origins may call my API from a browser?
Example:
Allow https://app.example.com to call https://api.example.com
CSRF
Question:
Can a malicious site cause the browser to send unwanted authenticated requests?
Memory sentence:
CORS controls browser cross-origin access.
CSRF protects against forged authenticated browser requests.
40. Method Security Preview
URL security:
.requestMatchers("/api/admin/**").hasRole("ADMIN")
Method security:
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) {
}
Method security protects service methods.
Useful when:
authorization depends on method arguments
same service method is called from multiple controllers
business-level permission is needed
We will study this later.
Memory sentence:
URL security protects endpoints. Method security protects methods.
41. Security and Service Layer
Do not put all business authorization only in URL rules.
Example:
GET /api/clients/10/tasks
URL rule can check:
user is authenticated
user has role USER
But business rule must check:
does this user belong to client 10?
does this user have tenant access?
This belongs in service/domain/security logic.
Memory sentence:
URL rules are not enough for data-level permissions.
42. Good Security Layering
A good design:
SecurityFilterChain -> basic endpoint access rules
Controller -> receives authenticated user/context
Service -> business permissions and tenant checks
Repository -> data access
Example:
@Transactional(readOnly = true)
public List<TaskDto> findClientTasks(Long clientId, String currentUserEmail) {
UserEntity user = userRepository.findByEmail(currentUserEmail)
.orElseThrow();
if (!permissionService.canAccessClient(user, clientId)) {
throw new AccessDeniedException("No access to client");
}
return taskRepository.findByClientId(clientId)
.stream()
.map(this::toDto)
.toList();
}
Memory sentence:
Endpoint security checks access to URLs; service security checks access to data and actions.
43. Security Exceptions
Common security outcomes:
not authenticated -> 401
authenticated but forbidden -> 403
Spring Security handles many of these before controllers.
Important:
Security exceptions often happen in filters before @ControllerAdvice.
So my MVC @RestControllerAdvice may not handle every security error.
Spring Security has its own exception handling configuration.
Memory sentence:
Security errors often happen before controller exception handling.
44. Common Beginner Surprise
After adding security starter:
implementation("org.springframework.boot:spring-boot-starter-security")
Suddenly:
GET /api/tasks returns 401
browser shows login page
Postman needs credentials
tests fail with 401/403
actuator endpoints may be protected
Why?
Spring Boot auto-configures default security.
Fix:
define your own SecurityFilterChain
configure public and protected endpoints
configure authentication method
adjust tests
Memory sentence:
Security starter changes endpoint behavior immediately.
45. Testing Security Preview
With Spring Security, controller tests may need authentication.
Example:
@WithMockUser(username = "user@example.com", roles = "USER")
@Test
void getsTasks() throws Exception {
mockMvc.perform(get("/api/tasks"))
.andExpect(status().isOk());
}
Without mock user:
test may return 401
We will study security testing later.
Memory sentence:
Security affects tests too.
46. Common Exam Traps
Trap 1
Spring Security runs before controllers.
Trap 2
Authentication and authorization are different.
Authentication = who are you?
Authorization = what are you allowed to do?
Trap 3
401 and 403 are different.
401 = not authenticated
403 = authenticated but not allowed
Trap 4
Spring Security is filter-chain based.
Trap 5
SecurityFilterChain is the modern way to configure web security.
Trap 6
HttpSecurity builds the SecurityFilterChain.
Trap 7
Rule order matters.
Specific rules should come before general rules.
Trap 8
hasRole("ADMIN") checks for authority ROLE_ADMIN.
Trap 9
Do not store raw passwords.
Use PasswordEncoder.
Trap 10
HTTP Basic must use HTTPS in real applications.
Trap 11
CSRF and CORS are different.
Trap 12
Do not disable CSRF blindly.
Trap 13
Security errors may happen before controller advice.
Trap 14
URL rules are not enough for tenant/data-level permissions.
Trap 15
Adding spring-boot-starter-security secures the app by default.
47. Real Exam Question: Spring Security
Question:
What problem does Spring Security solve?
Answer:
Spring Security provides authentication, authorization, and protection against common attacks for Spring applications.
48. Real Exam Question: Authentication
Question:
What is authentication?
Answer:
Authentication is the process of proving who the user is.
49. Real Exam Question: Authorization
Question:
What is authorization?
Answer:
Authorization is the process of deciding what an authenticated user is allowed to access or do.
50. Real Exam Question: Authentication vs Authorization
Question:
What is the difference between authentication and authorization?
Answer:
Authentication answers “Who are you?” Authorization answers “What are you allowed to do?”
51. Real Exam Question: 401 vs 403
Question:
What is the difference between 401 and 403?
Answer:
401 means the user is not authenticated or authentication failed. 403 means the user is authenticated but not allowed to access the resource.
52. Real Exam Question: Filters
Question:
Why does Spring Security use filters?
Answer:
Filters can intercept HTTP requests before they reach controllers, making them suitable for authentication, authorization, session handling, CSRF, and other security checks.
53. Real Exam Question: SecurityFilterChain
Question:
What is SecurityFilterChain?
Answer:
SecurityFilterChain defines the security filters and rules that apply to matching HTTP requests.
54. Real Exam Question: HttpSecurity
Question:
What is HttpSecurity?
Answer:
HttpSecurity is the builder used to configure web security and build a SecurityFilterChain.
55. Real Exam Question: SecurityContextHolder
Question:
What is SecurityContextHolder?
Answer:
SecurityContextHolder stores the current SecurityContext, which contains the current Authentication.
56. Real Exam Question: Role Prefix
Question:
What does hasRole("ADMIN") check?
Answer:
It checks for the authority ROLE_ADMIN.
57. Real Exam Question: PasswordEncoder
Question:
What is PasswordEncoder used for?
Answer:
PasswordEncoder is used to hash passwords and verify raw passwords against stored password hashes.
58. Real Exam Question: Default Security
Question:
What happens when I add spring-boot-starter-security to a Spring Boot web app?
Answer:
Spring Boot auto-configures default security. Commonly, endpoints become secured, a default user is created, and a generated password is printed in logs unless custom security configuration is provided.
59. Interview Answer
Question:
Explain the Spring Security request flow.
Good answer:
In a servlet-based Spring Boot application, an HTTP request goes through Spring Security filters before it reaches the DispatcherServlet. The filters can authenticate the user, populate the SecurityContext, check authorization rules, handle security exceptions, and then either block the request or allow it to continue to the controller. If the request is denied, the controller is not called.
60. Interview Answer
Question:
What is the difference between authentication and authorization?
Good answer:
Authentication is about proving identity, for example checking username and password or validating a JWT. Authorization is about permissions, for example checking whether the authenticated user has the ADMIN role or can access a specific client’s data. Authentication usually happens first, then authorization.
61. Interview Answer
Question:
What is
SecurityFilterChain?
Good answer:
SecurityFilterChain is the main configuration object for servlet web security in modern Spring Security. It defines which security filters and rules apply to requests. I usually create it as a bean using HttpSecurity, where I configure authorization rules, login method, CSRF, sessions, HTTP Basic, JWT resource server, and other security behavior.
62. Interview Answer
Question:
What is
SecurityContextHolder?
Good answer:
SecurityContextHolder stores the current SecurityContext, which contains the current Authentication. The Authentication represents the authenticated user, including principal, credentials, and authorities. Spring Security sets it during authentication so the application can know who the current user is.
63. Interview Answer
Question:
Why should passwords be encoded?
Good answer:
Passwords should never be stored as raw text. A PasswordEncoder performs a one-way transformation, usually a secure hash, so the stored value is not the original password. During login, Spring Security compares the raw password with the stored hash using matches. This reduces damage if the database is leaked.
64. Interview Answer
Question:
Why are URL rules not enough for real authorization?
Good answer:
URL rules can check broad access, such as requiring authentication or an admin role for an endpoint. But real applications often need data-level rules, such as whether a user belongs to a tenant, owns a resource, or may approve a specific invoice. Those checks usually belong in the service or domain layer, sometimes supported by method security.
65. Tiny Code Practice
Create this security config:
@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.build();
}
@Bean
UserDetailsService users(PasswordEncoder passwordEncoder) {
UserDetails user = User.builder()
.username("user@example.com")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
UserDetails admin = User.builder()
.username("admin@example.com")
.password(passwordEncoder.encode("password"))
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Questions:
- Who can access
/api/public/hello? - Who can access
/api/admin/users? - What does
anyRequest().authenticated()mean? - What authentication method is enabled?
- Why is
PasswordEncoderneeded?
Answers:
- Everyone.
- Only users with role
ADMIN. - Every other request requires authentication.
- HTTP Basic.
- To store and verify encoded password hashes.
66. Tiny Bug Practice 1
Problem:
.requestMatchers("/api/admin/**").hasRole("ROLE_ADMIN")
Question:
What is wrong?
Answer:
hasRole("ADMIN") automatically checks for authority ROLE_ADMIN. Passing "ROLE_ADMIN" to hasRole is usually wrong.
Correct:
.requestMatchers("/api/admin/**").hasRole("ADMIN")
or:
.requestMatchers("/api/admin/**").hasAuthority("ROLE_ADMIN")
67. Tiny Bug Practice 2
Problem:
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
.requestMatchers("/api/public/**").permitAll()
)
Question:
What is wrong?
Answer:
The general rule anyRequest().authenticated() comes before the specific public rule. Specific rules must come first.
Correct:
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/public/**").permitAll()
.anyRequest().authenticated()
)
68. Tiny Bug Practice 3
Problem:
@Bean
UserDetailsService users() {
UserDetails user = User.withUsername("user@example.com")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
Question:
What is wrong?
Answer:
The password is not encoded. Use PasswordEncoder.
Correct:
@Bean
UserDetailsService users(PasswordEncoder passwordEncoder) {
UserDetails user = User.builder()
.username("user@example.com")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
Practice Questions and Answers
Question 1
What problem does Spring Security solve?
Answer:
Spring Security provides authentication, authorization, and protection against common attacks for Spring applications.
Question 2
What is authentication?
Answer:
Authentication is proving who the user is.
Question 3
What is authorization?
Answer:
Authorization is deciding what the authenticated user is allowed to access or do.
Question 4
What is the difference between authentication and authorization?
Answer:
Authentication answers “Who are you?” Authorization answers “What are you allowed to do?”
Question 5
What is the difference between 401 and 403?
Answer:
401 means the user is not authenticated or authentication failed. 403 means the user is authenticated but not allowed.
Question 6
Why does Spring Security use filters?
Answer:
Filters can intercept HTTP requests before they reach controllers, so they are ideal for authentication, authorization, CSRF, sessions, and other security checks.
Question 7
Where does Spring Security run in relation to Spring MVC?
Answer:
Spring Security runs before Spring MVC controller methods.
Question 8
What is SecurityFilterChain?
Answer:
SecurityFilterChain defines the security filters and rules that apply to HTTP requests.
Question 9
What is HttpSecurity?
Answer:
HttpSecurity is the builder used to configure web security and build a SecurityFilterChain.
Question 10
What is FilterChainProxy?
Answer:
FilterChainProxy is the Spring Security component that delegates requests to the matching security filter chain.
Question 11
What happens when I add spring-boot-starter-security?
Answer:
Spring Boot auto-configures default security. Commonly, endpoints become secured, a default user exists, and a generated password is printed in logs unless custom configuration is provided.
Question 12
What does authorizeHttpRequests do?
Answer:
authorizeHttpRequests configures URL-based authorization rules.
Question 13
Why does rule order matter?
Answer:
Rules are evaluated in order. Specific rules should come before general rules like anyRequest().
Question 14
What does hasRole("ADMIN") check?
Answer:
It checks whether the user has authority ROLE_ADMIN.
Question 15
What is Authentication?
Answer:
Authentication represents the current authenticated user, including principal, credentials, authorities, and authenticated status.
Question 16
What is SecurityContextHolder?
Answer:
SecurityContextHolder stores the current SecurityContext, which contains the current Authentication.
Question 17
What is UserDetailsService?
Answer:
UserDetailsService loads user details by username for authentication.
Question 18
What is PasswordEncoder?
Answer:
PasswordEncoder hashes passwords and verifies raw passwords against stored password hashes.
Question 19
What is the difference between session-based security and stateless token security?
Answer:
Session-based security stores authentication state on the server and uses a session cookie. Stateless token security sends a token with every request and does not rely on server-side HTTP session authentication.
Question 20
Why are URL rules not enough for data-level permissions?
Answer:
URL rules can check broad endpoint access, but data-level permissions need business checks, such as whether a user may access a specific tenant, client, invoice, or task.
Final Memory Sentences
- Spring Security protects requests before controllers.
- Authentication means proving identity.
- Authorization means checking permissions.
- Authentication = who are you?
- Authorization = what can you do?
- 401 means not authenticated.
- 403 means authenticated but not allowed.
- Spring Security is filter-chain based.
- Security filters run before
DispatcherServlet. SecurityFilterChaindefines security filters and rules.HttpSecuritybuilds theSecurityFilterChain.FilterChainProxydelegates to security filter chains.- Adding
spring-boot-starter-securitysecures the app by default. authorizeHttpRequestsconfigures URL authorization.- Rule order matters.
- Specific rules go before general rules.
hasRole("ADMIN")checksROLE_ADMIN.Authenticationrepresents the current authenticated user.SecurityContextHolderstores the current security context.UserDetailsServiceloads users.PasswordEncoderstores and verifies password hashes.- Do not store raw passwords.
- HTTP Basic must use HTTPS in real apps.
- CSRF and CORS are different.
- URL rules are not enough for data-level permissions.