π° The Castle Gatekeeper: Spring Security Authorization
Imagine your application is a magnificent castle. Anyone can walk up to the gate, but only special people can enter specific rooms. Thatβs what Authorization does!
π The Big Picture: What is Authorization?
Think of a school building:
- Authentication = The guard checking your student ID at the entrance
- Authorization = The rules saying which classrooms YOU can enter
You proved WHO you are β
(Authentication)
Now we check WHAT you can do β
(Authorization)
Real Life Example
π« School Building
βββ π Library β All students allowed
βββ π¬ Science Lab β Only science students
βββ π’ Staff Room β Only teachers
βββ π Principal Office β Only principal
π‘οΈ Authorization Concepts
Authorization answers ONE simple question:
βIs THIS person allowed to do THAT thing?β
The Three Key Players
graph TD A["π€ User/Principal"] --> B{π Has Role?} B -->|Yes| C["β Access Granted"] B -->|No| D["β Access Denied"]
| Term | Simple Meaning | Example |
|---|---|---|
| Principal | The logged-in user | βJohnβ |
| Authority | Permission badge | βCAN_READ_REPORTSβ |
| Role | Job title (group of permissions) | βADMINβ, βUSERβ |
Code Example: Basic Setup
// User has ROLE_ADMIN
// Can access /admin/** pages
http
.authorizeHttpRequests()
.requestMatchers("/admin/**")
.hasRole("ADMIN");
π CSRF Protection: The Secret Handshake
What is CSRF?
Imagine someone tricks you into clicking a button that transfers YOUR money to THEIR account. Scary, right?
CSRF = Cross-Site Request Forgery A bad guy makes YOUR browser do bad things without YOU knowing
The Token Solution
graph TD A["π₯οΈ Server"] -->|Gives Secret Token| B["π Your Form"] B -->|Sends Token Back| C["π Server Checks"] C -->|Token Matches?| D["β Real Request!"] C -->|No Token?| E["β Fake Request!"]
How Spring Helps
// CSRF is ON by default! π
// Spring adds hidden token to all forms
// Your HTML form gets this automatically:
// <input type="hidden"
// name="_csrf"
// value="abc123-secret-token"/>
When to Disable (Rare!)
// Only for REST APIs with JWT tokens
http.csrf().disable();
// WHY? JWT tokens already prevent CSRF
// They're sent in headers, not cookies
πͺ Session Management: Remember Me!
What is a Session?
When you log in, the server gives you a visitor badge (session). You show this badge with every request so you donβt have to log in again.
Session Flow
graph TD A["π Login Success"] --> B["π« Get Session ID"] B --> C["πͺ Stored in Cookie"] C --> D["π€ Sent with Every Request"] D --> E["π Server Recognizes You"]
Spring Session Controls
http.sessionManagement()
// One login at a time
.maximumSessions(1)
// Kick out old session when new login
.maxSessionsPreventsLogin(false)
// Session timeout
.invalidSessionUrl("/login?expired")
// Create new session after login (security!)
.sessionFixation().newSession();
Session Settings Explained
| Setting | What It Does | Example |
|---|---|---|
maximumSessions(1) |
Only 1 device login | Canβt login from phone if laptop is active |
newSession() |
Fresh session after login | Prevents session hijacking |
invalidSessionUrl() |
Where to go when session dies | Redirect to login page |
π·οΈ Method Security Annotations
The Magic Decorators
Instead of configuring everything in one place, you can protect methods directly!
// First, enable it!
@EnableMethodSecurity
public class SecurityConfig { }
The Three Musketeers π‘οΈ
1. @PreAuthorize - Check BEFORE running
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) {
// Only admins can delete users
}
2. @PostAuthorize - Check AFTER running
@PostAuthorize("returnObject.owner == principal.username")
public Document getDocument(Long id) {
// You can only see YOUR documents
return documentRepo.findById(id);
}
3. @Secured - Simple role check
@Secured("ROLE_MANAGER")
public void approveExpense() {
// Only managers can approve
}
Quick Reference Table
| Annotation | When | Example Use |
|---|---|---|
@PreAuthorize |
Before method | βCan this user even try?β |
@PostAuthorize |
After method | βCan user see the result?β |
@Secured |
Before (simple) | Quick role check |
π Authorization Rules
Building Your Security Castle
@Bean
public SecurityFilterChain filterChain(
HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
// π Public pages (everyone)
.requestMatchers("/", "/home").permitAll()
// π€ User pages (logged in users)
.requestMatchers("/profile/**").authenticated()
// π Admin pages (admins only)
.requestMatchers("/admin/**").hasRole("ADMIN")
// π§ API endpoints (specific permission)
.requestMatchers("/api/reports/**")
.hasAuthority("VIEW_REPORTS")
// π« Everything else needs login
.anyRequest().authenticated()
);
return http.build();
}
Rule Priority = ORDER MATTERS! β οΈ
Rules are checked TOP to BOTTOM
First match wins!
β
Good Order:
/admin/secret β ADMIN only
/admin/** β MANAGER or ADMIN
/** β authenticated
β Bad Order:
/** β authenticated (catches everything!)
/admin/** β never reached π±
Common Matchers
| Method | Meaning |
|---|---|
permitAll() |
Anyone (even strangers) |
authenticated() |
Must be logged in |
hasRole("X") |
Must have ROLE_X |
hasAuthority("X") |
Must have exact permission X |
hasAnyRole("A","B") |
Must have A OR B |
denyAll() |
Nobody (block everything) |
π OAuth2 and JWT Basics
The VIP Pass System
OAuth2 = A way to let users login using Google, Facebook, etc. JWT = A special encoded ticket that contains user info
OAuth2: Login with Others
graph LR A["π€ User"] -->|Click 'Login with Google'| B["π΅ Google"] B -->|Who are you? Password?| A A -->|My Google password| B B -->|Here's proof token| C[π Your App] C -->|Token valid? User info please| B B -->|Yes! Here's email, name| C C -->|Welcome!| A
JWT: The Magic Ticket ποΈ
JWT = Three parts separated by dots
Header.Payload.Signature
eyJhbGc.eyJzdWI.SflKxw
| | |
| | βββ π Signature (proof it's real)
| βββ π¦ Payload (user info, expiry)
βββ π Header (token type, algorithm)
JWT Contains:
{
"sub": "john@email.com",
"roles": ["USER", "ADMIN"],
"exp": 1699999999
}
Spring OAuth2 + JWT Setup
// application.yml
spring:
security:
oauth2:
client:
registration:
google:
client-id: your-google-id
client-secret: your-secret
// Security Config for JWT
http
.oauth2Login() // Enable Google/FB login
.and()
.oauth2ResourceServer()
.jwt(); // Accept JWT tokens
OAuth2 vs JWT: When to Use?
| Feature | OAuth2 | JWT |
|---|---|---|
| Purpose | βLogin with Xβ | Stateless auth token |
| Session | Yes (usually) | No (token has all info) |
| Best For | User-facing apps | REST APIs |
| Example | βLogin with Googleβ | Mobile app β API |
π Putting It All Together
graph TD A["πͺ Request Arrives"] --> B{π Authenticated?} B -->|No| C["π Login Page"] B -->|Yes| D{π« CSRF Valid?} D -->|No| E["β Forbidden"] D -->|Yes| F{π Authorized?} F -->|No| G["β 403 Access Denied"] F -->|Yes| H["β Process Request"]
Real App Example
@Configuration
@EnableMethodSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain security(HttpSecurity http)
throws Exception {
return http
// Session: one device only
.sessionManagement(s -> s.maximumSessions(1))
// CSRF: enabled for web, disabled for API
.csrf(c -> c.ignoringRequestMatchers("/api/**"))
// Rules
.authorizeHttpRequests(a -> a
.requestMatchers("/public/**").permitAll()
.requestMatchers("/api/**").authenticated()
.requestMatchers("/admin/**").hasRole("ADMIN")
)
// OAuth2 login
.oauth2Login(Customizer.withDefaults())
.build();
}
}
π Key Takeaways
| Concept | One-Line Summary |
|---|---|
| Authorization | Checking WHAT you can do after knowing WHO you are |
| CSRF | Secret token prevents fake requests |
| Session | Your visitor badge that remembers you |
| @PreAuthorize | Guard before method runs |
| Authorization Rules | URL β Permission mapping |
| OAuth2 | Login with Google/Facebook/etc. |
| JWT | Encoded ticket with user info inside |
π‘ Remember: Authentication says βI know who you are.β Authorization says βHereβs what youβre allowed to do.β
Youβve just learned how to be the gatekeeper of your Spring castle! π°
