Spring Security Intro
Spring Security is the de-facto framework for securing Spring applications. It handles authentication (who you are), authorization (what you may do), and protection against common attacks like CSRF, session fixation, and clickjacking. In Spring Boot you add a single starter and get sensible, secure-by-default behavior that you then customize. This section targets Spring Security 6 (shipped with Spring Boot 3.5), which uses the SecurityFilterChain bean and the HttpSecurity lambda DSL.
What Spring Security gives you
Out of the box, Spring Security wires a chain of servlet filters in front of your application. Without writing a single line of configuration you get:
- Every endpoint protected — unauthenticated requests are redirected to a login form (or challenged with HTTP Basic for non-browser clients).
- A default user named
userwith a randomly generated password printed at startup. - A generated
/loginand/logoutpage. - Protection against CSRF, session fixation, and security response headers (
X-Content-Type-Options,Cache-Control, etc.).
Adding the starter
Add spring-boot-starter-security to your build. That single dependency pulls in spring-security-core, spring-security-config, and spring-security-web.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'
The moment this is on the classpath, Spring Boot’s SecurityAutoConfiguration activates and locks down your app.
Default behavior
Start the application and watch the console. Spring Boot generates a one-time password for the default user:
Using generated security password: 8e2f1c4a-7b3d-4f90-9a21-3c6d5e8f1b22
This generated password is for development use only.
Your security configuration must be updated before running your application in production.
Hit any endpoint and you’ll be challenged:
Request:
curl -i http://localhost:8080/api/hello
Output:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Realm"
Authenticate with the generated credentials:
curl -u user:8e2f1c4a-7b3d-4f90-9a21-3c6d5e8f1b22 http://localhost:8080/api/hello
You can override the default user with properties (useful only for quick demos):
spring.security.user.name=admin
spring.security.user.password=secret
spring.security.user.roles=ADMIN
Warning: The generated password and
spring.security.user.*properties are for local development only. Real applications define users via in-memory or database authentication.
Authentication vs authorization
These two concepts are the foundation of everything in this section. Keep them distinct.
| Concept | Question it answers | Spring component |
|---|---|---|
| Authentication | ”Who are you?” | AuthenticationManager, UserDetailsService, PasswordEncoder |
| Authorization | ”Are you allowed to do this?” | authorizeHttpRequests, @PreAuthorize, roles/authorities |
Authentication runs first: the user proves their identity (password, token, certificate). The result is an Authentication object stored in the SecurityContextHolder. Authorization runs afterward, checking that authenticated principal’s roles and authorities against the rules you declare.
// After login, this is available anywhere in the request thread
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
A first custom configuration
The modern way to configure security is a SecurityFilterChain @Bean. Here is a minimal example that permits a public path and secures everything else:
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/public/**").permitAll()
.anyRequest().authenticated())
.httpBasic(basic -> {})
.formLogin(form -> {});
return http.build();
}
}
Note: As soon as you declare any
SecurityFilterChainbean, Spring Boot backs off its auto-configured chain and uses yours. Configure everything you need explicitly.
In This Section
- Security Filter Chain — how requests flow through Spring Security’s filters.
- Configuring Security — the
SecurityFilterChainbean and request matchers. - In-Memory Authentication — define users in code for demos and tests.
- Database Authentication — load users from JPA via
UserDetailsService. - Password Encoding — BCrypt and the delegating encoder.
- Authorization & Roles — roles, authorities, and request-level rules.
- Method-Level Security —
@PreAuthorizeand SpEL on service methods. - CSRF Protection — when it matters and when to disable it.
- CORS with Security — wiring CORS into the filter chain.