Implementing Spring Security
1. Adding Spring Security Dependencies
Example: Spring Security dependencies
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-security</ artifactId >
</ dependency >
< dependency >
< groupId >org.springframework.security</ groupId >
< artifactId >spring-security-test</ artifactId >
< scope >test</ scope >
</ dependency >
Note: Out of the box: HTTP Basic, generated user/password, CSRF on, all
endpoints secured.
2. Configuring Security Filter Chain
Example: Stateless JWT security filter chain
@ Configuration
@ EnableWebSecurity
public class SecurityConfig {
@ Bean
SecurityFilterChain api (HttpSecurity http ) throws Exception {
return http
. csrf (csrf -> csrf. disable ())
. cors (Customizer. withDefaults ())
. sessionManagement (s -> s. sessionCreationPolicy (STATELESS))
. authorizeHttpRequests (a -> a
. requestMatchers ( "/public/**" , "/actuator/health" ). permitAll ()
. requestMatchers ( "/admin/**" ). hasRole ( "ADMIN" )
. anyRequest (). authenticated ())
. oauth2ResourceServer (o -> o. jwt (Customizer. withDefaults ()))
. build ();
}
}
3. Using In-Memory Authentication
Example: In-memory users with encoded passwords
@ Bean
UserDetailsService users (PasswordEncoder enc) {
return new InMemoryUserDetailsManager (
User. withUsername ( "admin" ). password (enc. encode ( "secret" )). roles ( "ADMIN" ). build (),
User. withUsername ( "user" ). password (enc. encode ( "pwd" )). roles ( "USER" ). build ()
);
}
4. Using JDBC Authentication
Example: JDBC-backed user details
@ Bean
UserDetailsService jdbcUsers (DataSource ds) {
return new JdbcUserDetailsManager (ds);
}
Default Tables
Schema
users
username, password, enabled
authorities
username, authority
5. Implementing UserDetailsService Interface
Example: Load user from database
@ Service
public class DbUserDetailsService implements UserDetailsService {
private final UserRepository repo;
public DbUserDetailsService (UserRepository repo ) { this .repo = repo; }
@ Override public UserDetails loadUserByUsername (String username ) {
return repo. findByEmail (username)
. map (u -> User. withUsername (u. getEmail ())
. password (u. getPasswordHash ())
. roles (u. getRoles (). toArray ( String [] ::new ))
. build ())
. orElseThrow (() -> new UsernameNotFoundException (username));
}
}
6. Configuring Password Encoders
Encoder
Recommendation
BCryptPasswordEncoder
Default; cost 10–12
Argon2PasswordEncoder
Modern, memory-hard (preferred new apps)
Pbkdf2PasswordEncoder
FIPS-compliant
SCryptPasswordEncoder
Memory-hard alt
DelegatingPasswordEncoder
Default — supports {bcrypt}, {argon2} prefixes
Example: Delegating password encoder
@ Bean PasswordEncoder encoder () {
return PasswordEncoderFactories. createDelegatingPasswordEncoder ();
}
7. Securing Endpoints with HTTP Security
Matcher
Use
requestMatchers("/api/**")
Ant patterns
permitAll()
Open
denyAll()
Block
authenticated()
Any auth user
hasRole("X") / hasAuthority("SCOPE_x")
Role / authority check
access(expr)
SpEL or AuthorizationManager
8. Using Method-Level Security
Example: Method security: role and ownership check
@ Configuration
@ EnableMethodSecurity
public class MethodSecConfig {}
@ Service
public class OrderService {
@ PreAuthorize ( "hasRole('ADMIN') or #ownerId == authentication.name" )
public Order get (String ownerId , Long id ) { /* … */ }
@ PostAuthorize ( "returnObject.owner == authentication.name" )
public Document load (Long id ) { /* … */ }
}
9. Configuring CORS
Example: CORS configuration source bean
@ Bean
CorsConfigurationSource corsSource () {
CorsConfiguration cfg = new CorsConfiguration ();
cfg. setAllowedOrigins (List. of ( "https://app.example.com" ));
cfg. setAllowedMethods (List. of ( "GET" , "POST" , "PUT" , "DELETE" ));
cfg. setAllowedHeaders (List. of ( "*" ));
cfg. setAllowCredentials ( true );
UrlBasedCorsConfigurationSource src = new UrlBasedCorsConfigurationSource ();
src. registerCorsConfiguration ( "/**" , cfg);
return src;
}
10. Implementing CSRF Protection
Mode
When
Default (cookie/header)
Browser-based form / SPA with cookie auth
Disabled
Stateless API with bearer token
CookieCsrfTokenRepository.withHttpOnlyFalse()
SPA reading XSRF-TOKEN cookie
11. Configuring Session Management
Policy
Behavior
ALWAYS
Always create session
IF_REQUIRED (default)
Create when needed
NEVER
Use existing only
STATELESS
JWT/API style — no session
12. Using Security Context (SecurityContextHolder)
Example: Read username and roles from context
Authentication auth = SecurityContextHolder. getContext (). getAuthentication ();
String username = auth. getName ();
boolean isAdmin = auth. getAuthorities (). stream ()
. anyMatch (a -> "ROLE_ADMIN" . equals (a. getAuthority ()));
Strategy
Use
MODE_THREADLOCAL (default)
Per-thread
MODE_INHERITABLETHREADLOCAL
Child threads inherit
MODE_GLOBAL
JVM-wide (rarely useful)