Spring Security Notes
Spring Security Notes
Spring Security 1
1. Define Roles and Authorities
2. Database Structure for Roles
3. Implement UserDetailsService for Role Management
4. Assign Roles to Users
5. Enforce Role-Based Access Control in Spring Security
a) Securing URLs
b) Method-Level Security
Key Components:
1. Security Filters: A filter chain that intercepts HTTP requests and applies
security logic. Examples include UsernamePasswordAuthenticationFilter ,
BasicAuthenticationFilter , etc.
Spring Security 2
2. AuthenticationManager: Manages the process of authenticating users. It
delegates the authentication request to one or more AuthenticationProvider s.
The filter chain is a series of security filters that handle different security
concerns. The core filter responsible for authentication is
UsernamePasswordAuthenticationFilter .
2. Authentication Begins
The UsernamePasswordAuthenticationFilter kicks in when a user submits their
credentials (usually via a form submission).
This filter extracts the username and password from the request and
creates an Authentication object (commonly a
UsernamePasswordAuthenticationToken ).
Spring Security 3
The filter passes the Authentication object to the AuthenticationManager .
4. Authentication Providers
The AuthenticationManager delegates the authentication request to one or
more AuthenticationProvider s. Each AuthenticationProvider is responsible for a
particular type of authentication (e.g., LDAP, JDBC, OAuth).
import [Link];
import [Link]
n;
import [Link]
cationManager;
import [Link]
[Link];
import [Link]
tailsService;
import [Link]
swordEncoder;
import [Link]
dEncoder;
@Configuration
public class SecurityConfig {
Spring Security 4
@Bean
public UserDetailsService userDetailsService() {
// Your custom UserDetailsService implementation he
re
return username -> {
// Fetch the user from the database and return
a UserDetails object
};
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(Auth
enticationConfiguration authenticationConfiguration) throws
Exception {
return [Link]
nManager();
}
}
6. Successful Authentication
If the credentials are valid, the AuthenticationProvider returns a fully
populated Authentication object, indicating the user is successfully
authenticated.
Spring Security 5
If the application is configured for session management, the security
context is stored in the user’s session, allowing for persistent authentication
across multiple requests.
The application continues processing the request with the user’s authorities
considered for authorization decisions.
is invoked.
Typically, the user is redirected back to the login page with an error
message indicating the failure.
import [Link];
import [Link]
n;
import [Link].b
[Link];
import [Link]
n;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecu
rity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/login", "/register").per
mitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
Spring Security 6
.loginPage("/login")
.failureHandler(customAuthenticationFailure
Handler())
.defaultSuccessUrl("/home")
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.permitAll()
);
return [Link]();
}
@Bean
public CustomAuthenticationFailureHandler customAuthent
icationFailureHandler() {
return new CustomAuthenticationFailureHandler(); //
Replace with your custom failure handler logic
}
}
import [Link]
cationProvider;
Spring Security 7
import [Link];
import [Link]
ption;
import [Link]
tails;
import [Link]
tailsService;
import [Link]
dEncoder;
import [Link];
@Component
public class CustomAuthenticationProvider implements Authen
ticationProvider {
public CustomAuthenticationProvider(UserDetailsService
userDetailsService, PasswordEncoder passwordEncoder) {
[Link] = userDetailsService;
[Link] = passwordEncoder;
}
@Override
public Authentication authenticate(Authentication authe
ntication) throws AuthenticationException {
String username = [Link]();
String password = (String) [Link]
tials();
Spring Security 8
} else {
throw new AuthenticationException("Invalid user
name or password") {};
}
}
@Override
public boolean supports(Class<?> authentication) {
return [Link]
AssignableFrom(authentication);
}
}
Configuring ProviderManager
In Spring Security 6, you don't directly configure ProviderManager as you did in
previous versions. Instead, Spring automatically wires the AuthenticationProvider s
into the ProviderManager when they are defined as beans. Here’s how you can
include your custom AuthenticationProvider :
javaCopy code
import [Link];
import [Link]
n;
import [Link]
cationManager;
import [Link]
[Link];
@Configuration
public class SecurityConfig {
Spring Security 9
ationProvider;
}
@Bean
public AuthenticationManager authenticationManager(Auth
enticationConfiguration authenticationConfiguration) throws
Exception {
return [Link]
nManager();
}
}
Description: When the user submits their login form, the request is
intercepted by UsernamePasswordAuthenticationFilter . The attemptAuthentication()
method extracts the username and password from the request and creates
an Authentication object (typically a UsernamePasswordAuthenticationToken ).
2. Delegating to AuthenticationManager
Class: AuthenticationManager (commonly implemented by ProviderManager )
3. Authentication by AuthenticationProvider
Spring Security 10
Class: AuthenticationProvider (e.g., DaoAuthenticationProvider )
javaCopy code
[Link]().setAuthentication(authRe
sult);
Spring Security 11
Description: The SecurityContextPersistenceFilter is responsible for storing
the SecurityContext containing the Authentication object into the HTTP
session or other persistence mechanisms. This ensures that the user
remains authenticated across multiple requests.
javaCopy code
SecurityContext contextBeforeChainExecution = [Link]
ext(holder);
[Link](contextBeforeChainExecutio
n);
[Link](targetUrl);
Spring Security 12
Class: Application Code (any part of the application)
Method: [Link]().getAuthentication()
Description: At any point in the application, you can retrieve the currently
authenticated user's details by accessing the SecurityContextHolder . This
allows you to perform authorization checks, get user-specific data, etc.
debugging:
[Link]=DEBUG
@EnableWebSecurity(debug = true)
Managing users
In-Memory User Management
Before transitioning to database-backed user management, let's briefly recap
how in-memory user management is typically configured:
import [Link];
import [Link]
n;
import [Link]
[Link];
import [Link].b
[Link];
import [Link];
import [Link]
tails;
import [Link]
tailsService;
Spring Security 13
import [Link]
erDetailsManager;
import [Link]
n;
@Configuration
public class SecurityConfig {
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUs
erDetailsManager();
[Link]([Link]
()
.username("user")
.password("password")
.roles("USER")
.build());
[Link]([Link]
()
.username("admin")
.password("admin")
.roles("ADMIN")
.build());
return manager;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecu
rity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults());
return [Link]();
}
Spring Security 14
}
Spring Security 15
the necessary database connection details.
[Link] Example:
[Link]=jdbc:mysql://localhost:3306/yourdatab
ase
[Link]=yourusername
[Link]=yourpassword
[Link]-class-name=[Link]
r
[Link]-auto=update
import [Link];
import [Link]
antedAuthority;
import [Link]
tails;
import [Link]
tailsService;
import [Link]
meNotFoundException;
import [Link];
import [Link];
import [Link];
import [Link];
@Service
public class CustomUserDetailsService implements UserDetail
sService {
Spring Security 16
private final DataSource dataSource;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// Load user from the 'users' table
User user = findUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not f
ound with username: " + username);
}
Spring Security 17
g., JPA)
// Example: SELECT * FROM users WHERE username = ?
}
import [Link];
import [Link]
n;
import [Link]
[Link];
import [Link].b
[Link];
import [Link]
swordEncoder;
import [Link]
dEncoder;
import [Link]
n;
@Configuration
Spring Security 18
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecu
rity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults());
return [Link]();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(Auth
enticationManagerBuilder auth) throws Exception {
[Link](customUserDetailsService)
.passwordEncoder(passwordEncoder());
return [Link]();
}
}
Spring Security 19
Role management
Managing roles and authorization in Spring Security involves several steps to
ensure that users have the correct access rights within your application. This
includes defining roles, assigning roles to users, and enforcing role-based
access control throughout your application.
Spring Security 20
roles table: Stores the different roles available in the system.
import [Link];
import [Link]
antedAuthority;
import [Link]
tails;
import [Link]
tailsService;
import [Link]
meNotFoundException;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Service
public class CustomUserDetailsService implements UserDetail
sService {
Spring Security 21
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = findUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not f
ound with username: " + username);
}
Spring Security 22
PreparedStatement statement = [Link]
eStatement(
"SELECT [Link] FROM roles r INNER JOIN user
_roles ur ON [Link] = ur.role_id WHERE ur.user_id = ?"
);
[Link](1, userId);
ResultSet rs = [Link]();
while ([Link]()) {
[Link](new SimpleGrantedAuthority
([Link]("name")));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return authorities;
}
}
a) Securing URLs
You can specify which roles are allowed to access specific URLs in your
SecurityConfig :
Spring Security 23
javaCopy code
import [Link];
import [Link]
n;
import [Link].b
[Link];
import [Link]
n;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecu
rity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER",
"ADMIN")
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
)
.formLogin(withDefaults());
return [Link]();
}
}
b) Method-Level Security
Spring Security 24
You can also enforce role-based access at the method level using annotations:
@Secured Annotation:
import [Link]
cured;
@Service
public class AdminService {
@Secured("ROLE_ADMIN")
public void performAdminTask() {
// Only admins can perform this task
}
}
import [Link]
thorize;
@Service
public class UserService {
@PreAuthorize("hasRole('ADMIN') or hasRole('USER')")
public void performUserTask() {
// Both admins and users can perform this task
}
}
import [Link]
Spring Security 25
n;
import [Link]
[Link];
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostE
nabled = true)
public class MethodSecurityConfig {
// Other configurations if needed
}
Spring Security 26