Spring Security
https://nitinkc.github.io/spring-security-reference/ Spring Security is a framework focused on providing authentication, authorization, and other security features for Java applications.
- Comprehensive support for authentication and authorization.
- Protection against common vulnerabilities (e.g., CSRF, session fixation).
- Integration with OAuth2 for Single Sign-On (SSO).
- Security for REST APIs, including stateless authentication mechanisms like JWT.
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Core Concepts
Fundamental Concepts
-
Authentication: The process of verifying the identity of a user, device, or system. It answers the question, “Who are you?”.
- Example: Logging in with a username and password.
-
Authorization: The process of determining whether an authenticated user has permission to access a specific
resource or perform a particular action. It answers the question, “What are you allowed to do?”.
-
Example: Granting access to the admin dashboard only to users with the
ADMINrole.
-
Example: Granting access to the admin dashboard only to users with the
-
Principal: The currently authenticated user. It can be represented as an object within Spring Security’s
SecurityContext.
SecurityContextHolder, SecurityContext, and Authentication
SecurityContextHolder: This is the heart of Spring Security’s authentication mechanism.
It’s where the framework stores the details of the currently authenticated principal. By default, it uses a ThreadLocal
to store these details, making the security context available throughout a single thread of execution.
SecurityContext: Held by the SecurityContextHolder, this contains the Authentication object.
Authentication: This interface represents the token for an authentication request. It contains:
-
getPrincipal(): The identity of the principal being authenticated. -
getCredentials(): The credentials that prove the principal’s identity (e.g., a password). -
getAuthorities(): The permissions granted to the principal (e.g., roles).
UserDetails and UserDetailsService
UserDetails: Provides core user information. It’s a contract for a user’s details, including username, password,
authorities, and account status (e.g., enabled, locked).
UserDetailsService: An interface used to load user-specific data. It has a single method, loadUserByUsername(String username),
which is responsible for locating the user from a persistent store (like a database) and returning a UserDetails object.
GrantedAuthority
This interface represents a permission granted to the principal. These are typically roles (e.g., ROLE_USER, ROLE_ADMIN).
PasswordEncoder
- Used for encoding passwords before storing them.
- Spring Security requires a
PasswordEncoderto be configured.BCryptPasswordEncoderis a common and secure choice.
Example using BCryptPasswordEncoder:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Authentication Architecture
Authentication is the process of verifying who a user is.
sequenceDiagram
participant User
participant UsernamePasswordAuthenticationFilter
participant AuthenticationManager
participant AuthenticationProvider
participant UserDetailsService
participant SecurityContextHolder
User->>UsernamePasswordAuthenticationFilter: Submits credentials (username/password)
UsernamePasswordAuthenticationFilter->>AuthenticationManager: Creates AuthenticationToken and calls authenticate()
AuthenticationManager->>AuthenticationProvider: Delegates to appropriate provider
AuthenticationProvider->>UserDetailsService: loadUserByUsername()
UserDetailsService-->>AuthenticationProvider: Returns UserDetails
AuthenticationProvider->>AuthenticationProvider: Compares passwords (using PasswordEncoder)
alt Credentials are valid
AuthenticationProvider-->>AuthenticationManager: Returns fully authenticated Authentication object
AuthenticationManager-->>UsernamePasswordAuthenticationFilter: Returns Authentication object
UsernamePasswordAuthenticationFilter->>SecurityContextHolder: setAuthentication(authentication)
SecurityContextHolder-->>UsernamePasswordAuthenticationFilter:
UsernamePasswordAuthenticationFilter-->>User: Authentication successful, grants access
else Credentials are invalid
AuthenticationProvider-->>AuthenticationManager: Throws AuthenticationException
AuthenticationManager-->>UsernamePasswordAuthenticationFilter: Throws AuthenticationException
UsernamePasswordAuthenticationFilter-->>User: Authentication failed, denies access
end
AuthenticationManager, ProviderManager, and AuthenticationProvider
-
AuthenticationManager: The main strategy interface for authentication. Itsauthenticate()method attempts to authenticate the passedAuthenticationobject. -
ProviderManager: The most common implementation ofAuthenticationManager. It delegates to a list of configuredAuthenticationProviderinstances. -
AuthenticationProvider: Responsible for a specific authentication mechanism (e.g., username/password, LDAP, SAML). It attempts to authenticate a user and returns a fully populatedAuthenticationobject if successful.
SecurityFilterChain
In modern Spring Security (post-WebSecurityConfigurerAdapter), security is configured via SecurityFilterChain beans.
This chain of filters intercepts incoming requests to enforce security rules.
Key filters include:
-
UsernamePasswordAuthenticationFilter: Processes authentication form submissions. -
BasicAuthenticationFilter: Handles HTTP Basic authentication. -
FilterSecurityInterceptor: Responsible for authorization, checking if a user has access to a resource.
Authorization
Authorization is the process of deciding if a user is allowed to do something.
Role-Based vs. Permission-Based Access Control
-
Role-Based Access Control (RBAC): Access is granted based on roles assigned to users (e.g.,
ADMIN,USER). -
Permission-Based Access Control: More granular. Access is granted based on specific permissions (e.g.,
READ_PRIVILEGE,WRITE_PRIVILEGE).
Method Security Annotations
-
@PreAuthorize: Checks for authorization before a method is executed. Uses SpEL (Spring Expression Language) for powerful expressions.@PreAuthorize("hasRole('ADMIN')") public void adminMethod() { // Code here } -
@PostAuthorize: Checks for authorization after a method is executed. Useful when you need to check the return value. -
@Secured: A simpler annotation for role-based checks:@Secured("ROLE_ADMIN") public void adminMethod() { // Code here } -
@RolesAllowed: The JSR-250 standard annotation for specifying roles.
Web Security
HttpSecurity Configuration
The HttpSecurity object is used to configure web-based security for all HTTP requests. You can configure:
- URL-based authorization rules (
requestMatchers). - Login and logout behavior.
- CORS and CSRF protection.
- Session management.
Basic Authentication Example
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults());
return http.build();
}
}
CORS (Cross-Origin Resource Sharing)
A mechanism that allows resources to be requested from another domain. Spring Security provides comprehensive CORS support that can be configured within the HttpSecurity configuration.
CSRF (Cross-Site Request Forgery)
An attack that tricks a victim into submitting a malicious request. Spring Security provides CSRF protection by default. It requires a token to be included in all state-changing requests.
To disable (e.g., for stateless REST APIs):
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable());
return http.build();
}
JWT (JSON Web Token)
JWT is a compact, URL-safe means of representing claims to be transferred between two parties. It’s commonly used for stateless authentication in microservices.
The flow is typically:
- User authenticates with credentials.
- Server generates a JWT and sends it to the client.
- Client includes the JWT in the
Authorizationheader for subsequent requests. - A custom filter on the server validates the JWT and sets the
Authenticationin theSecurityContextHolder.
Key classes for implementation:
JwtAuthenticationFilterJwtTokenProvider
OAuth2 and OpenID Connect (OIDC)
-
OAuth2: An authorization framework that enables a third-party application to obtain limited access to an HTTP service. Key roles:
- Resource Owner: The user.
- Client: The application requesting access.
- Authorization Server: The server that authenticates the Resource Owner and issues access tokens.
- Resource Server: The server that hosts the protected resources.
- OIDC: A thin layer on top of OAuth2 that adds an identity layer, providing information about the authenticated user.
Example configuration for OAuth2 with Google:
spring.security.oauth2.client.registration.google.client-id=your-client-id
spring.security.oauth2.client.registration.google.client-secret=your-client-secret
Testing Spring Security
-
@WithMockUser: Mocks a user with a specific username, password, and roles. -
@WithUserDetails: Loads a user from theUserDetailsServiceto use for a test. -
MockMvc: Can be used with Spring Security to test web-layer security by performing requests and asserting the responses.