Skip to main content

Spring Security

Getting Started

Add Spring Security Dependency

pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security will automatically add basic authentication to all endpoints once this dependency is added.

Understanding Key Components

  • Authentication: Verifies the user's identity.
  • Authorization: Determines if an authenticated user has permission to perform specific actions.
  • Principal: Represents the current authenticated user in the application.
  • Roles & Authorities: Roles are high-level groupings of authorities (permissions) that define access levels.

Configuring Authentication

You can use multiple methods for authentication in Spring Security:

In-Memory Authentication (for Prototyping or Testing)

Configure in-memory authentication with specific users and roles.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER")
.and()
.withUser("admin").password("{noop}admin").roles("ADMIN");
}
}
info

{noop} is a password encoder that tells Spring Security to expect plain text. Use other password encoders like BCryptPasswordEncoder in production.

Database Authentication

For production, authenticate users from a database.

  1. Define a UserDetailsService implementation that fetches user details from the database.
  2. Use a Password Encoder for storing hashed passwords.
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

JWT Authentication

To use JWT tokens for authentication:

  1. Create a login endpoint that generates a JWT upon successful authentication.
  2. Configure a JWTAuthenticationFilter to validate tokens on each request.

Authorization: Configuring Access Control

Authorization configurations control access to resources based on roles or permissions.

Role-Based Access Control

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}

Method-Level Authorization

Use annotations to restrict access at the method level:

  • @PreAuthorize – To check access before method execution.
  • @Secured – Specify roles required to access the method.
@PreAuthorize("hasRole('ADMIN')")
public void someAdminMethod() {
// Method logic
}

Enable method-level security with:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends WebSecurityConfigurerAdapter {
}

Handling CORS and CSRF

CORS (Cross-Origin Resource Sharing)

Enable CORS for REST APIs that might be accessed from a different domain:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://allowed-origin.com"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}

CSRF (Cross-Site Request Forgery)

By default, CSRF is enabled. You can disable it for stateless APIs (like JWT):

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
warning

Only disable CSRF if you know it is not needed, such as with stateless REST APIs.

Session Management

Spring Security manages sessions by default. You can configure session policies to meet your security requirements:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS); // For JWT or token-based authentication
}

Options:

  • SessionCreationPolicy.ALWAYS: Always create a session.
  • SessionCreationPolicy.IF_REQUIRED: Create a session only if required.
  • SessionCreationPolicy.NEVER: Never create a session but use one if it exists.
  • SessionCreationPolicy.STATELESS: Do not store sessions.

Custom Authentication & Authorization Logic

To add custom authentication:

  1. Create an AuthenticationProvider to customize user validation.
  2. Implement custom filters for additional request checks (e.g., OncePerRequestFilter).

Configuring OAuth2 and Social Login

For OAuth2 authentication:

  1. Add the spring-boot-starter-oauth2-client dependency.
  2. Configure application.yml or application.properties with your provider settings.
spring:
security:
oauth2:
client:
registration:
google:
client-id: your-client-id
client-secret: your-client-secret
scope: profile, email

Spring Boot simplifies this setup with OAuth providers like Google, GitHub, etc.

Testing Security Configurations

  1. Unit Testing: Use @WithMockUser to simulate users with specific roles for testing.
  2. Integration Testing: Test endpoints with and without authentication to verify security configurations.
@Test
@WithMockUser(username = "user", roles = {"USER"})
public void whenUserAccessUserPage_thenSuccess() throws Exception {
mvc.perform(get("/user/page")).andExpect(status().isOk());
}

Best Practices

  • Use Strong Password Encoders: Always use a secure password encoder like BCryptPasswordEncoder.
  • Limit Session and Token Lifespan: Configure session timeouts or token expiration to reduce attack windows.
  • Enable HTTPS: Secure communications by configuring HTTPS in production.
  • Restrict Sensitive Endpoints: Limit access to admin or critical endpoints by roles or permissions.
  • Use Custom Error Handling: Customize error messages for failed authentications to avoid information disclosure.