Skip to main content

Chapter 1: Introduction to Spring Security

Introduction​

Before configuring anything, it is essential to understand how Spring Security works. This chapter lays the foundations that will allow you to configure security correctly.


🎯 Chapter Objectives​

By the end of this chapter, you will know:

  1. ✅ Why security is essential
  2. ✅ The difference between Authentication and Authorization
  3. ✅ The architecture of Spring Security
  4. ✅ How the filter chain works
  5. ✅ Key concepts: Principal, Credentials, Authorities

1. Why Secure an Application?​

Threats​

Real Examples​

YearCompanyImpact
2023MOVEit60M+ users affected
2021Facebook533M accounts exposed
2019Capital One100M+ data stolen
2017Equifax147M personal data

The 3 Pillars of Security (CIA)​

┌─────────────────────────────────────────────────┐
│ │
│ C - Confidentiality │
│ Only authorized people │
│ can view the data │
│ │
│ I - Integrity │
│ Data cannot be │
│ modified without authorization │
│ │
│ A - Availability │
│ The system remains accessible │
│ to legitimate users │
│ │
└─────────────────────────────────────────────────┘

2. Authentication vs Authorization​

The Fundamental Difference​

ConceptQuestionExample
Authentication"Who are you?"Login with email/password
Authorization"Do you have the right?"Access /admin (reserved for admins)

Analogy: The VIP Club​

In Spring Security​

// Authentication: Who is logged in?
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName(); // "john@example.com"

// Authorization: What are their rights?
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
// [ROLE_USER] - Not ROLE_ADMIN!

3. Architecture of Spring Security​

Overview​

Key Components​

1. SecurityFilterChain​

The filter chain that intercepts ALL requests:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.build();
}
}

2. AuthenticationManager​

Coordinates authentication:

3. UserDetailsService​

Interface for loading users:

public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

4. PasswordEncoder​

Encodes passwords (NEVER in plain text!):

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

// Usage
String encoded = passwordEncoder.encode("myPassword");
// $2a$10$N9qo8uLOickgx2ZMRZoMye...

boolean matches = passwordEncoder.matches("myPassword", encoded);
// true

4. The Filter Chain in Detail​

Order of Filters (Simplified)​

1. CorsFilter                    → CORS Management
2. CsrfFilter → CSRF Protection
3. LogoutFilter → Logout Management
4. UsernamePasswordAuthFilter → Form Login
5. BasicAuthenticationFilter → HTTP Basic Auth
6. BearerTokenAuthFilter → JWT/OAuth2
7. AnonymousAuthenticationFilter → Anonymous User
8. ExceptionTranslationFilter → Error Management
9. FilterSecurityInterceptor → Final Access Decision

Flow Visualization​


5. Key Concepts​

Principal​

The identity of the logged-in user:

@GetMapping("/profile")
public String profile(Principal principal) {
String username = principal.getName();
return "Welcome " + username;
}

Authentication Object​

Contains all authentication information:

public interface Authentication {
Collection<? extends GrantedAuthority> getAuthorities(); // Roles/Permissions
Object getCredentials(); // Password (often erased after auth)
Object getDetails(); // Additional details (IP, etc.)
Object getPrincipal(); // The user (UserDetails)
boolean isAuthenticated();
}

GrantedAuthority​

Represents a role or permission:

// Roles (prefix ROLE_)
new SimpleGrantedAuthority("ROLE_ADMIN");
new SimpleGrantedAuthority("ROLE_USER");

// Permissions
new SimpleGrantedAuthority("READ_USERS");
new SimpleGrantedAuthority("WRITE_USERS");
new SimpleGrantedAuthority("DELETE_USERS");

SecurityContext​

Stores the current user's Authentication:

// Retrieve the logged-in user
SecurityContext context = SecurityContextHolder.getContext();
Authentication auth = context.getAuthentication();

if (auth != null && auth.isAuthenticated()) {
String username = auth.getName();
// ...
}

UserDetails​

Interface representing a user:

public interface UserDetails {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}

6. Types of Authentication​

1. Form Login (Session)​

Client → POST /login (user, pass)
Server → Set-Cookie: JSESSIONID=xyz
Client → GET /api/data (Cookie: JSESSIONID=xyz)
Server → Verify session → 200 OK

Advantages: Simple, managed by the browser Disadvantages: Not suitable for stateless REST APIs

2. HTTP Basic​

Client → GET /api/data
Server → 401 + WWW-Authenticate: Basic
Client → GET /api/data (Authorization: Basic base64(user:pass))
Server → 200 OK

Advantages: Simple Disadvantages: Credentials sent with every request

3. JWT (Token)​

Client → POST /login (user, pass)
Server → {"token": "eyJhbGciOiJIUzI1..."}
Client → GET /api/data (Authorization: Bearer eyJhbGciOiJIUzI1...)
Server → Verify token → 200 OK

Advantages: Stateless, perfect for REST APIs Disadvantages: Expiration management

4. OAuth2​

Client → Redirect to Google
Google → User login
Google → Redirect with code
Server → Exchange code for token
Server → Retrieve user profile

Advantages: No password management, modern UX Disadvantages: External dependency


7. Modern Configuration (Spring Security 6+)​

Old Method (Deprecated)​

// ❌ DO NOT USE
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated();
}
}

New Method (Spring Security 6+)​

// ✅ USE THIS APPROACH
@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.build();
}

@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}

8. First Configuration​

Maven Dependency​

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Default Behavior​

Without any configuration, Spring Security:

  • Protects ALL endpoints
  • Generates a random password (displayed in logs)
  • Activates form login on /login
  • Activates logout on /logout
Using generated security password: 8e3d7a2c-1234-5678-abcd-ef0123456789

Minimal Configuration​

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/home", "/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.permitAll()
)
.logout(logout -> logout
.permitAll()
)
.build();
}
}

9. Summary​

Key Concepts​

ConceptDescription
AuthenticationVerify identity (who?)
AuthorizationVerify rights (what?)
SecurityFilterChainSecurity filter chain
AuthenticationManagerOrchestrates authentication
UserDetailsServiceLoads users
PasswordEncoderEncodes passwords
SecurityContextStores the current user

Simplified Architecture​

HTTP Request
↓
SecurityFilterChain (filters)
↓
AuthenticationManager
↓
UserDetailsService + PasswordEncoder
↓
SecurityContext (storage)
↓
Application (Controller)

Important Points​

✅ Spring Security 6+ uses @Bean, not extends WebSecurityConfigurerAdapter
✅ Always encode passwords (BCrypt)
✅ Understand Authentication vs Authorization
✅ Security is configured via SecurityFilterChain

🎯 Next Step​

Now that you understand the architecture, let's move on to practice with basic authentication.

➡️ Chapter 2: Basic Authentication


⬅️ Back to Module 8