0% found this document useful (0 votes)
3 views10 pages

Spring Security Notes

Spring Security is a customizable authentication and access-control framework for Java applications, focusing on authentication and authorization. It features a Security Filter Chain that intercepts HTTP requests, provides various authentication methods including JWT and OAuth2, and supports method-level security through annotations. Key components include SecurityContextHolder, UserDetailsService, and PasswordEncoder, with best practices emphasizing secure password storage and proper CSRF handling.

Uploaded by

yadeedya katuri
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views10 pages

Spring Security Notes

Spring Security is a customizable authentication and access-control framework for Java applications, focusing on authentication and authorization. It features a Security Filter Chain that intercepts HTTP requests, provides various authentication methods including JWT and OAuth2, and supports method-level security through annotations. Key components include SecurityContextHolder, UserDetailsService, and PasswordEncoder, with best practices emphasizing secure password storage and proper CSRF handling.

Uploaded by

yadeedya katuri
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Spring Security

Complete Developer Notes & Revision Guide


Authentication · Authorization · Filters · JWT · OAuth2

1. What is Spring Security?


Spring Security is a powerful, highly customizable authentication and access-control framework for
Java applications. It is the de-facto standard for securing Spring-based applications.

🔑 Spring Security handles: WHO are you? (Authentication) and WHAT can you do? (Authorization)

Core Capabilities
• Authentication — verifying user identity (login)
• Authorization — controlling access to resources
• Protection against common attacks: CSRF, Session Fixation, Clickjacking, XSS
• Servlet API integration, works seamlessly with Spring MVC
• Supports OAuth2, OpenID Connect, SAML, LDAP, JWT

📝 Spring Security works by adding a chain of Servlet Filters before your application code executes.

2. Core Architecture
2.1 The Security Filter Chain
Spring Security intercepts every HTTP request using a chain of filters. Each filter has a specific job. The
order matters.

HTTP Request


┌─────────────────────────────────┐
│ SecurityFilterChain │
│ ┌──────────────────────────┐ │
│ │ 1. SecurityContextHolder │ │
│ │ 2. UsernamePasswordFilter│ │
│ │ 3. BasicAuthFilter │ │
│ │ 4. BearerTokenFilter │ │
│ │ 5. ExceptionTranslation │ │
│ │ 6. FilterSecurityInterc. │ │
│ └──────────────────────────┘ │
└─────────────────────────────────┘


Your Application
2.2 Key Components

Component Responsibility
SecurityContextHolder Stores authentication info for the current request (ThreadLocal)
SecurityContext Contains the Authentication object
Authentication Represents the authenticated principal (user + credentials +
authorities)
AuthenticationManager Entry point — delegates to AuthenticationProvider(s)
AuthenticationProvider Does the actual authentication (DB lookup, LDAP, etc.)
UserDetailsService Loads user-specific data from DB. You implement this!
UserDetails Core user information (username, password, authorities)
GrantedAuthority Represents a permission/role (e.g., ROLE_ADMIN)
PasswordEncoder Encodes and verifies passwords (BCrypt recommended)
AccessDecisionManager Makes authorization decisions (permit or deny)

🔑 You almost always only need to implement UserDetailsService and configure HttpSecurity. Spring
handles the rest.

3. Authentication Flow (Step by Step)


Form Login Flow
• 1. User submits login form (POST /login)
• 2. UsernamePasswordAuthenticationFilter extracts credentials
• 3. Creates UsernamePasswordAuthenticationToken (unauthenticated)
• 4. Passes it to AuthenticationManager (ProviderManager)
• 5. ProviderManager delegates to DaoAuthenticationProvider
• 6. DaoAuthenticationProvider calls [Link]()
• 7. Compares password using PasswordEncoder
• 8. Returns authenticated Authentication object
• 9. Stored in SecurityContextHolder
• 10. User redirected to success URL

📝 If authentication fails, AuthenticationFailureHandler is called. SecurityContextHolder is cleared.

How to Implement UserDetailsService


@Service
public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = [Link](username)
.orElseThrow(() -> new UsernameNotFoundException(
"User not found: " + username));

return new [Link](


[Link](),
[Link](), // must be BCrypt-encoded!
getAuthorities([Link]())
);
}

private List<GrantedAuthority> getAuthorities(Set<Role> roles) {


return [Link]()
.map(r -> new SimpleGrantedAuthority("ROLE_" + [Link]()))
.collect([Link]());
}
}

4. Configuration — SecurityFilterChain
In Spring Security 6+ (Spring Boot 3+), configuration is done via SecurityFilterChain bean. The old
WebSecurityConfigurerAdapter is deprecated.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> [Link]()) // disable for REST APIs
.sessionManagement(session -> session
.sessionCreationPolicy([Link]))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/user/**").hasAnyRole("USER","ADMIN")
.anyRequest().authenticated()
)
.authenticationProvider(authenticationProvider())
.addFilterBefore(jwtAuthFilter,
[Link]);

return [Link]();
}

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

@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration config) throws Exception {
return [Link]();
}
}

🔑 permitAll() — no auth required. authenticated() — any logged-in user. hasRole() — specific role
needed.

5. JWT Authentication (Most Common in REST APIs)


Why JWT?
• Stateless — no server-side session storage
• Scalable — works across multiple servers
• Self-contained — carries user info inside the token

JWT Structure
A JWT has 3 parts separated by dots: [Link]
eyJhbGciOiJIUzI1NiJ9 <- Header (algorithm)
.eyJzdWIiOiJ1c2VyMSJ9 <- Payload (claims: sub, roles, exp)
.SflKxwRJSMeKKF2QT4fwpMeJf <- Signature (secret-signed)

JWT Flow in Spring Security


• 1. User logs in → server validates credentials → returns JWT token
• 2. Client stores JWT (localStorage or cookie)
• 3. Every subsequent request includes: Authorization: Bearer <token>
• 4. JWT Filter extracts and validates the token
• 5. Sets Authentication in SecurityContextHolder
• 6. Request proceeds to controller

JWT Filter Implementation


@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired private JwtService jwtService;


@Autowired private UserDetailsService userDetailsService;

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {

String authHeader = [Link]("Authorization");


if (authHeader == null || ![Link]("Bearer ")) {
[Link](request, response);
return;
}
String jwt = [Link](7);
String username = [Link](jwt);

if (username != null && [Link]()


.getAuthentication() == null) {
UserDetails userDetails =
[Link](username);

if ([Link](jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails, null, [Link]());
[Link](
new WebAuthenticationDetailsSource().buildDetails(request));
[Link]()
.setAuthentication(authToken);
}
}
[Link](request, response);
}
}

📝 Always use OncePerRequestFilter to ensure the filter runs exactly once per request.

6. Authorization — Method-Level Security


Beyond URL-based security, Spring Security supports method-level security via annotations. Enable it
with:
@EnableMethodSecurity // on your @Configuration class

Key Annotations
Annotation Usage
@PreAuthorize Check permission BEFORE method executes. Most powerful —
supports SpEL.
@PostAuthorize Check permission AFTER method executes (can inspect return
value).
@Secured Simple role check. No SpEL. E.g., @Secured("ROLE_ADMIN")
@RolesAllowed JSR-250 equivalent of @Secured.

@PreAuthorize Examples
// Only ADMIN can access
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) { ... }

// User can only access their own data


@PreAuthorize("#userId == [Link]")
public User getUser(Long userId) { ... }
// Check specific permission
@PreAuthorize("hasAuthority('user:write')")
public void updateProfile(Profile p) { ... }

// Multiple conditions
@PreAuthorize("hasRole('ADMIN') or #username == [Link]")
public void resetPassword(String username) { ... }

🔑 hasRole('ADMIN') automatically prepends ROLE_ prefix. hasAuthority('ROLE_ADMIN') does not.

7. Password Encoding
NEVER store plain-text passwords. Spring Security provides PasswordEncoder interface.

// Bean definition
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // strength 10 by default
}

// Encoding on registration
[Link]([Link](rawPassword));

// Verification (Spring does this automatically during login)


boolean matches = [Link](rawPassword, encodedPassword);

Encoder Notes
BCryptPasswordEncoder Recommended. Adaptive work factor. Adds salt automatically.
Argon2PasswordEncoder Most secure. Memory-hard. Preferred for high-security apps.
SCryptPasswordEncoder Memory and CPU intensive. Good alternative to BCrypt.
NoOpPasswordEncoder NEVER use in production. Only for testing.

8. CSRF Protection
What is CSRF?
Cross-Site Request Forgery tricks a logged-in user's browser into making unwanted requests. Spring
Security enables CSRF protection by default for web apps.

When to Disable CSRF


• REST APIs using stateless JWT tokens — safe to disable
• APIs consumed by non-browser clients (mobile apps, Postman)
• When using CORS properly with token-based auth

// Disable CSRF for REST APIs


.csrf(csrf -> [Link]())

// Enable CSRF for web apps (default)


.csrf([Link]())

// CSRF token in Thymeleaf forms is added automatically


📝 Stateful web applications using session cookies MUST keep CSRF enabled.

9. OAuth2 & OpenID Connect


OAuth2 Roles
Role Description
Resource Owner The user (you)
Client Your application requesting access
Authorization Server Issues tokens (Google, GitHub, Okta, Keycloak)
Resource Server Holds the data your app wants (e.g., Google profile API)

Spring Boot OAuth2 Login Setup


# [Link]
spring:
security:
oauth2:
client:
registration:
google:
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
scope: openid, profile, email

// Security Config
.oauth2Login(oauth2 -> oauth2
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt([Link]()) // for API resource server
)
🔑 OAuth2 login = delegation of authentication. The provider (Google) authenticates the user. You
receive their profile.

10. SecurityContextHolder
The SecurityContextHolder is the heart of Spring Security. It stores the current authenticated user's
details.

// Get current user anywhere in code


Authentication auth = SecurityContextHolder
.getContext().getAuthentication();

String username = [Link]();


Collection<? extends GrantedAuthority> roles = [Link]();

// Get UserDetails object


UserDetails user = (UserDetails) [Link]();

// In a Controller — cleaner approach


@GetMapping("/profile")
public String getProfile(@AuthenticationPrincipal UserDetails userDetails) {
return [Link]();
}

📝 SecurityContextHolder uses ThreadLocal by default — each thread/request has its own security context.

11. Common Annotations Reference


Annotation Purpose
@EnableWebSecurity Activates Spring Security. Put on @Configuration class.
@EnableMethodSecurity Enables @PreAuthorize, @PostAuthorize etc.
@PreAuthorize Authorization check before method with SpEL.
@PostAuthorize Authorization check after method — can use returnObject.
@Secured Simple role-based security.
@AuthenticationPrincipal Inject current user into controller method.
@WithMockUser Used in tests to mock authenticated user.

12. Exception Handling


Spring Security throws two main exceptions you must handle:

Exception Meaning
AuthenticationException User is NOT authenticated (401 Unauthorized). E.g., bad
credentials, expired token.
AccessDeniedException User IS authenticated but lacks permission (403 Forbidden).

.exceptionHandling(ex -> ex
.authenticationEntryPoint((request, response, authException) -> {
[Link](HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
})
.accessDeniedHandler((request, response, accessDeniedException) -> {
[Link](HttpServletResponse.SC_FORBIDDEN, "Forbidden");
})
)
13. Testing with Spring Security
@SpringBootTest
@AutoConfigureMockMvc
class SecurityTest {

@Autowired MockMvc mockMvc;

@Test
@WithMockUser(username = "alice", roles = {"USER"})
void userCanAccessProfile() throws Exception {
[Link](get("/api/profile"))
.andExpect(status().isOk());
}

@Test
void unauthenticatedCannotAccess() throws Exception {
[Link](get("/api/profile"))
.andExpect(status().isUnauthorized());
}

@Test
@WithMockUser(roles = {"USER"})
void userCannotAccessAdmin() throws Exception {
[Link](get("/api/admin"))
.andExpect(status().isForbidden());
}
}

14. Quick Revision Cheatsheet


Authentication vs Authorization
• Authentication = WHO are you? (login, identity verification)
• Authorization = WHAT can you do? (permissions, access control)

Spring Security 6 Key Changes


• WebSecurityConfigurerAdapter removed — use SecurityFilterChain @Bean
• Method chaining replaced with lambda DSL
• @EnableMethodSecurity replaces @EnableGlobalMethodSecurity
• authorizeHttpRequests replaces authorizeRequests

Most Common Mistakes


• Forgetting ROLE_ prefix: hasRole('ADMIN') looks for ROLE_ADMIN authority
• Not encoding passwords with BCrypt before saving to DB
• Leaving CSRF enabled for REST APIs — causes 403 errors from Postman
• Not setting JWT filter before UsernamePasswordAuthenticationFilter
• Using SecurityContextHolder in async code without context propagation
Security Best Practices
• Always use BCryptPasswordEncoder (minimum strength 10)
• Use HTTPS in production
• Keep JWT expiry short (15 min to 1 hr) and use refresh tokens
• Never store JWTs in localStorage for sensitive apps — use HttpOnly cookies
• Use @PreAuthorize over URL-based rules for granular control
• Validate and sanitize all input regardless of authentication
• Log security events (failed logins, access denials) for audit trails

Interview Quick Answers


Question Answer
How does Spring Security work Servlet Filter Chain intercepts requests, authenticates via
internally? AuthenticationManager, authorizes via AccessDecisionManager.
Difference between 401 and 401 = not authenticated. 403 = authenticated but no permission.
403?
What is UserDetailsService? Interface you implement to tell Spring Security how to load user
from DB.
Why BCrypt? Adaptive hashing with built-in salt. Makes brute-force attacks
computationally expensive.
JWT vs Session? JWT is stateless (scalable). Session is stateful (simpler, but
requires sticky sessions or shared store).
What is SecurityContextHolder? Thread-local store that holds the Authentication object for the
current request.

Spring Security Developer Notes — Compiled for revision and quick reference

You might also like