BackendBench
Coffee

Unravel › Java concepts › Security

Spring

Spring Security basics

Spring Security puts a chain of filters in front of your application.

Learn these first

At a glance

Mental model

A building with a front desk and keycards.

What happens, in order
  1. 1Every request passes through a SecurityFilterChainYou configure it with HttpSecurity: which paths are public, which need a login, how login works (form, HTTP basic, JWT bearer token).
  2. 2After a successful login the identity is stored in the SecurityContext, available through SecurityContextHolder or as a controller parameter with @AuthenticationPrincipalIt is held per thread for the duration of the request.
  3. 3Method-level rules such as @PreAuthorize("hasRole('ADMIN')") protect individual service methods; they work through proxies and need @EnableMethodSecurity
  4. 4Passwords must never be stored or compared as plain textA PasswordEncoder (typically BCryptPasswordEncoder) hashes on registration and verifies on login.
Remember
Watch out
Putting a permissive rule before restrictive onesStoring passwords unhashed or with a fast hashChecking roles but not ownership of the resourceDisabling CSRF without understanding the consequenceExpecting the logged-in user inside a new thread
Example (highlighted lines explain it)
@BeanSecurityFilterChain filterChain(HttpSecurity http) throws Exception {    http.authorizeHttpRequests(a -> a            .requestMatchers("/health", "/public/**").permitAll()            .requestMatchers("/admin/**").hasRole("ADMIN")            .anyRequest().authenticated())        .httpBasic(Customizer.withDefaults());    return http.build();}
  1. line 2 uses SecurityFilterChain, the core of Spring Security basics
Read the full explanation (about 2 min)

Spring Security puts a chain of filters in front of your application. They work out who the caller is (authentication) and whether they may do what they ask (authorization), before a controller is reached.

A mental model

A building with a front desk and keycards. The desk checks who you are and hands you a card; every door then checks whether your card opens it. The rooms never have to ask for ID themselves.

How it works

Every request passes through a SecurityFilterChain. You configure it with HttpSecurity: which paths are public, which need a login, how login works (form, HTTP basic, JWT bearer token).

After a successful login the identity is stored in the SecurityContext, available through SecurityContextHolder or as a controller parameter with @AuthenticationPrincipal. It is held per thread for the duration of the request.

Method-level rules such as @PreAuthorize("hasRole('ADMIN')") protect individual service methods; they work through proxies and need @EnableMethodSecurity.

Passwords must never be stored or compared as plain text. A PasswordEncoder (typically BCryptPasswordEncoder) hashes on registration and verifies on login.

Going deeper

Rules are matched top to bottom and the first match wins, so a broad anyRequest().permitAll() placed early silently opens everything below it. Put specific rules first and end with anyRequest().authenticated().

CSRF protection is on by default for browser sessions and rightly so; disable it only for stateless APIs that use tokens in headers, and understand why before you do.

Authentication proves identity; authorization checks permission on each object. Checking only the role ("is a user") and not ownership ("is this order theirs?") is the classic access-control bug.

The security context is thread-bound. Work handed to another thread (an @Async method, an executor) does not see the logged-in user unless you propagate the context.

Under the hood

The filters are registered as one FilterChainProxy in the servlet container. Each filter handles a concern (session lookup, token parsing, CSRF, exception translation, authorization). Authorization decisions are made by an AuthorizationManager that compares the Authentication with the rule for the request or method.

Common mistakes

  • Putting a permissive rule before restrictive ones.
  • Storing passwords unhashed or with a fast hash.
  • Checking roles but not ownership of the resource.
  • Disabling CSRF without understanding the consequence.
  • Expecting the logged-in user inside a new thread.

How Unravel recognises it

When you paste code, Unravel looks for these signs of spring security basics. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Builds on this

Frequently asked questions

What is Spring Security basics?

Spring Security puts a chain of filters in front of your application. They work out who the caller is (authentication) and whether they may do what they ask (authorization), before a controller is reached.

What are the most common mistakes with Spring Security basics?

Putting a permissive rule before restrictive ones. Storing passwords unhashed or with a fast hash. Checking roles but not ownership of the resource. Disabling CSRF without understanding the consequence. Expecting the logged-in user inside a new thread.

How can I see Spring Security basics in real code?

Paste your own Java into Unravel and it will point out where spring security basics appears, explain how it works at the detail level you choose, and draw the flow of the code around it.