HttpSecurity
About
HttpSecurity is a Spring Security class that allows developers to configure security policies for their applications. It provides a fluent API to define security rules, including authentication, authorization, session management, CSRF protection, CORS, and custom security filters.
It is highly customizable and is used inside the SecurityFilterChain bean.
Responsibilities of HttpSecurity
Responsibility
Description
Authentication Configuration
Specifies login mechanisms (e.g., form-based login, HTTP Basic, OAuth2, JWT, etc.). Defines custom authentication filters.
Authorization Rules
Controls access to different resources based on user roles and permissions. Supports method-level security.
Session Management
Configures session policies (e.g., stateless sessions for REST APIs). Prevents session fixation attacks.
Cross-Site Request Forgery (CSRF) Protection
Enables or disables CSRF protection. Allows fine-grained control over CSRF behavior.
Cross-Origin Resource Sharing (CORS) Policies
Configures CORS rules for handling requests from different origins.
Security Headers Management
Sets HTTP security headers such as Strict-Transport-Security, X-Frame-Options, etc.
Adding Custom Security Filters
Allows adding custom authentication and authorization filters at specific positions in the filter chain.
Sample Usage
A standard Spring Security configuration using HttpSecurity looks like this -
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // Disable CSRF for APIs
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll() // Allow public access
.requestMatchers("/admin/**").hasRole("ADMIN") // Only ADMIN can access
.anyRequest().authenticated() // All other requests need authentication
)
.formLogin(Customizer.withDefaults()) // Enable default form-based login
.logout(logout -> logout.logoutUrl("/logout").permitAll()); // Custom logout settings
return http.build();
}
}Authentication Configuration
Spring Security allows authentication configuration through HttpSecurity. The authentication mechanism determines how users provide credentials and how the system validates them.
Syntax for Authentication Configuration
Authentication is configured inside a SecurityFilterChain bean:
authorizeHttpRequests(auth -> auth...)→ Defines access rules for different endpoints.requestMatchers("/public/**").permitAll()→ Allows access without authentication.requestMatchers("/admin/**").hasRole("ADMIN")→ Restricts access to users with theADMINrole.anyRequest().authenticated()→ Requires authentication for all other endpoints.httpBasic(Customizer.withDefaults())→ Enables Basic Authentication.formLogin(Customizer.withDefaults())→ Enables Form-Based Authentication.
1. Basic Authentication
HTTP Basic Authentication is a simple authentication scheme where the client sends a username and password in the Authorization header of each request. The credentials are Base64-encoded but not encrypted, making it insecure over HTTP (use HTTPS only). Suitable for APIs or internal applications where user sessions are not needed.
Configuring Basic Authentication
How Basic Authentication Works
The client sends a request with an
Authorizationheader:(Where
dXNlcjpwYXNzd29yZA==isuser:passwordencoded in Base64)Spring Security decodes the credentials and checks them against the user database.
If valid, access is granted; otherwise, a
401 Unauthorizedresponse is returned.
When to Use Basic Authentication
When working with REST APIs that don't require session management.
When using stateless authentication (e.g., microservices).
2. Form-Based Authentication
Form-Based Authentication uses an HTML login page where users enter their credentials. The credentials are submitted to a login endpoint, verified by Spring Security, and a session is created.
Configuring Form-Based Authentication
How Form-Based Authentication Works
The user navigates to
/loginand enters their credentials.The credentials are sent via
POSTto/login(default endpoint).Spring Security authenticates the user and creates a session.
If successful, the user is redirected to
/home.If failed, they are redirected to
/login?error=true.
When to Use Form-Based Authentication
When building web applications that require session-based authentication.
Customizing Login & Logout
3. JWT Authentication (Using Custom Filter)
JWT (JSON Web Token) Authentication is a stateless authentication mechanism. A token is generated after login and sent with each request instead of using sessions.
Configuring JWT Authentication
Create a Custom JWT Filter
Register JWT Filter in Security Configuration
How JWT Authentication Works
User logs in and receives a JWT token.
The token is included in the Authorization header (
Bearer <token>) for every request.The JWT filter extracts and validates the token.
If valid, authentication is set in the SecurityContext.
4. OAuth2 Login (Social Logins)
Allows authentication using external providers like Google, Facebook, GitHub, etc. Users don't need to enter credentials in the application; they authenticate via the provider.
Configuring OAuth2 Login
How OAuth2 Authentication Works
The user is redirected to Google/GitHub/etc. for login.
After authentication, the provider sends an authorization code.
Spring Security exchanges this code for an access token.
The application retrieves user details and grants access.
Authorization Rules
Authorization determines what actions an authenticated user can perform. Spring Security provides several ways to define access control, including:
Role-Based Access Control (RBAC)
Method-Level Security
Configuring Authorization Rules in Spring Security
Spring Security defines authorization rules inside the SecurityFilterChain using authorizeHttpRequests().
Basic Authorization Configuration
permitAll()→ Allows access to everyone (unauthenticated users).hasRole("USER")→ Allows only users with the USER role.hasRole("ADMIN")→ Restricts access to users with the ADMIN role.anyRequest().authenticated()→ Requires authentication for all other endpoints.
1. Role-Based Access Control
RBAC is a security model where access is granted based on user roles.
Defining User Roles
In Spring Security, user roles are typically stored in a UserDetailsService.
Example: Creating a User with Roles
The
roles()method automatically prefixes "ROLE_" to the given role names.roles("USER")becomesROLE_USERin the system.
Role-Based Authorization in Security Configuration
hasAuthority() vs. hasRole()
Method
Description
hasRole("ADMIN")
Checks if user has ROLE_ADMIN (Spring Security adds the ROLE_ prefix).
hasAuthority("REPORT_VIEW")
Checks if user has the specific authority/permission (without ROLE_ prefix).
hasAnyRole("USER", "ADMIN")
Allows users with either ROLE_USER or ROLE_ADMIN.
hasAnyAuthority("READ_PRIVILEGES", "WRITE_PRIVILEGES")
Allows users with at least one of the specified permissions.
Storing Permissions Instead of Roles
If we need fine-grained permissions (e.g., READ_PRIVILEGES, EDIT_POST), use Authorities instead of roles.
Roles → Used for broad access control (e.g.,
ROLE_ADMIN,ROLE_USER).Authorities → Used for fine-grained permissions (e.g.,
EDIT_POST,DELETE_USER).
2. Method-Level Security
Spring Security allows restricting access at the method level using annotations.
Enabling Method Security
Add @EnableMethodSecurity in the configuration class:
@PreAuthorize - Check Before Method Execution
Example: Restricting API Calls
@PreAuthorize("hasRole('ADMIN')") → Only allows users with ROLE_ADMIN to execute the method.
@PostAuthorize - Check After Method Execution
Used when authorization depends on the returned object.
The method runs first, and then Spring Security checks if the returned object's username matches the logged-in user.
@Secured - Alternative to @PreAuthorize
Unlike @PreAuthorize, @Secured does not support SpEL expressions.
@RolesAllowed - JSR-250 Alternative
Works like @Secured, but allows specifying multiple roles.
Combining Role-Based & Method-Level Security
Combining URL-Based Security (authorizeHttpRequests()) and Method-Level Security (@PreAuthorize, @PostAuthorize) provides multiple layers of security, ensuring that:
Unauthorized requests are blocked as early as possible (at the filter level).
Granular, context-aware security rules can be enforced at the service level.
Example: Combining Both Approaches
Controller with Method-Level Security
Session Management
Session management controls how user sessions are created, maintained, and invalidated in a Spring Security-based application. It is crucial for:
Security (Preventing session hijacking, session fixation)
Performance (Reducing server memory usage)
Scalability (Especially for REST APIs where stateless authentication is preferred)
Configuring Session Management in Spring Security
Spring Security allows configuring session management using sessionManagement() in the HttpSecurity configuration.
Stateless Session (For REST APIs)
REST APIs should be stateless to ensure scalability and avoid session-based authentication overhead.
Why Stateless Sessions for REST APIs?
Improves scalability (No need to store session data in memory)
Better performance (Avoids extra lookups for session validation)
Ideal for microservices (No need for session replication across nodes)
How to Implement Stateless Sessions in Spring Security?
Use SessionCreationPolicy.STATELESS to disable session management.
sessionCreationPolicy(SessionCreationPolicy.STATELESS)→ Prevents the creation of a session.No
HttpSessionis stored or used → Every request must include authentication (e.g., JWT token).Disables CSRF (
csrf.disable()) → CSRF protection is not needed in stateless APIs.Custom JWT Filter (
JwtAuthenticationFilter) → Extracts user authentication from JWT in each request.
Example: Custom JWT Authentication Filter
Extracts the JWT token from the request header.
Validates the token and retrieves user details.
Sets the user authentication in
SecurityContextHolder.
Preventing Session Fixation Attacks
A session fixation attack occurs when an attacker tricks a user into using a known session ID, allowing them to hijack the session after login.
How to Prevent Session Fixation?
Spring Security provides built-in protection using sessionFixation().
Session Fixation Strategies in Spring Security
Strategy
Description
migrateSession() (Default)
Creates a new session ID but retains session attributes.
newSession()
Creates a completely new session, discarding previous session attributes.
none()
No protection against session fixation (not recommended).
Example: Custom Login Handler to Invalidate Old Sessions
Invalidates old sessions after successful login.
Prevents session fixation attacks by creating a new session.
Managing Concurrent Sessions
Spring Security allows limiting the number of concurrent sessions per user.
Explanation
maximumSessions(1)→ Restricts users to a single active session.maxSessionsPreventsLogin(true)→ Prevents a new login if the user is already logged in elsewhere.
CSRF Protection
Cross-Site Request Forgery (CSRF) is a web security vulnerability that allows an attacker to execute unauthorized actions on behalf of an authenticated user. Spring Security provides built-in CSRF protection, which is enabled by default for web applications. However, for stateless APIs, it is typically disabled.
CSRF attacks occur when:
A user is authenticated in a web application.
The user visits a malicious site that sends a request to the application.
The request executes an action on behalf of the authenticated user without their knowledge.
Disabling CSRF for APIs
Since REST APIs are typically stateless, CSRF protection is not needed. API clients (e.g., mobile apps, Postman) do not rely on browser cookies, which makes CSRF attacks irrelevant.
Why Disable CSRF for APIs?
REST APIs do not use cookies for authentication.
Tokens (JWT, OAuth2) are used instead of session-based authentication.
CSRF attacks require authentication via cookies, which is not applicable for APIs.
Enabling CSRF for Web Applications
For web applications using session-based authentication (cookies), CSRF protection should remain enabled.
csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())→ Stores the CSRF token in a cookie, making it accessible to JavaScript for AJAX requests.withHttpOnlyFalse()→ Allows JavaScript to read the token for AJAX calls.
How the CSRF Token Works Here?
Spring Security sends a CSRF token in a cookie (
XSRF-TOKEN).The frontend must send the token in the
X-CSRF-TOKENheader in AJAX requests.
Example: Fetching the CSRF Token in JavaScript
CORS
CORS is a security mechanism implemented by browsers to restrict cross-origin HTTP requests. It prevents unauthorized websites from making requests to your backend services.
Same-Origin Policy (SOP): By default, browsers block requests if the origin (protocol, domain, and port) is different from the requested resource.
CORS Policy: CORS allows web applications to bypass SOP and make cross-origin requests by defining allowed origins, methods, headers, etc.
Spring provides multiple ways to configure CORS:
Using
WebMvcConfigurer(Global CORS Policy)Using
HttpSecurity(Security-Specific CORS Configuration)Configuring it for specific controllers
CORS Configuration
Spring Security adds an additional layer of security that might override global CORS settings. We need to explicitly enable it in HttpSecurity.
This configures CORS inside Spring Security, ensuring security rules don’t block valid requests.
Uses
CorsConfigurationSourceto define allowed origins, methods, and headers.
Security Headers
Apart from CORS, Spring Security also enforces security headers to protect against various web vulnerabilities.
Default Security Headers Added by Spring Security
Spring Security adds the following headers automatically:
Header
Purpose
X-Frame-Options: DENY
Prevents Clickjacking attacks.
X-Content-Type-Options: nosniff
Prevents MIME type sniffing.
Strict-Transport-Security
Forces HTTPS connections.
X-XSS-Protection: 1; mode=block
Protects against XSS attacks.
Content-Security-Policy
Prevents inline JavaScript execution.
Customizing Security Headers
If we need custom headers, we can configure them using HttpSecurity.headers().
contentSecurityPolicy("default-src 'self'")→ Restricts resources to the same domain.frameOptions(frame -> frame.sameOrigin())→ Allows embedding only from the same domain.xssProtection(xss -> xss.block(true))→ Enables XSS blocking.
Disabling Security Headers (Not Recommended)
We might need to disable certain headers in some cases, e.g., when using custom security mechanisms.
Custom Security Filters
A security filter in Spring Security is a component that intercepts HTTP requests and applies security logic before passing them to the application.
Spring Security uses a filter chain to process authentication, authorization, and other security concerns.
Filters allow us to modify request/response handling at different stages.
Custom filters are needed when:
Adding custom authentication mechanisms (e.g., API key authentication).
Logging request details for security auditing.
Implementing rate limiting for APIs.
Validating JWT tokens in a custom way.
Modifying headers before passing requests to controllers.
Adding a Custom Filter
Example: Logging All Incoming Requests
Let’s create a filter that logs request details before passing them to controllers.
OncePerRequestFilterensures the filter runs once per request.Logs request details (
methodandURI).Passes control to the next filter (
filterChain.doFilter(...)).
Registering the Filter in Spring Security
We need to add the filter to the Spring Security filter chain.
addFilterBefore(requestLoggingFilter, UsernamePasswordAuthenticationFilter.class)→ Runs the custom filter before authentication.
Last updated