The Actuator Security Problem Spring Boot Actuator exposes endpoints that reveal sensitive information about your application — environment variables, configuration properties, heap dumps, thread dumps, and the ability to shut down the application remotely. An exposed /actuator/env endpoint can leak database passwords, API keys, and JWT signing secrets. An exposed /actuator/shutdown is a denial-of-service button. Actuator security is not optional in production. Actuator Endpoints and Their Risk Level Endpoint Exposes Risk /actuator/health Application health Low — often public /actuator/info App metadata Low /actuator/metrics JVM/HTTP metrics Medium — business data /actuator/env All configuration properties (including secrets) Critical /actuator/configprops All @ConfigurationProperties values Critical /actuator/loggers Log levels (writable) High /actuator/heapdump Full JVM heap as a file Critical /actuator/threaddump Thread state Medium /actuator/mappings All URL mappings Medium — reveals API surface /actuator/shutdown Kills the JVM Critical /actuator/auditevents Security events High Step 1: Expose Only What You Need By default, only health is exposed over HTTP.
Continue reading »Spring Security Tutorial
30 posts in this section
AuthenticationManager, AuthenticationProvider, and UserDetailsService
The Authentication Delegation Chain Spring Security separates requesting authentication from performing authentication. A filter receives a username and password — but it does not check them itself. It passes the request to AuthenticationManager, which delegates to one or more AuthenticationProvider instances: flowchart LR F[Authentication Filter\nForm Login / Basic / JWT] -->|UsernamePasswordToken| AM[AuthenticationManager\nProviderManager] AM -->|try each provider| AP1[DaoAuthenticationProvider\nfor DB users] AM -->|try each provider| AP2[LdapAuthenticationProvider\nfor LDAP users] AM -->|try each provider| AP3[Custom Provider\nfor API key] AP1 -->|if supported| UDS[UserDetailsService\nloadUserByUsername] UDS --> DB[(Database)] AP1 -->|verify password| PE[PasswordEncoder] AP1 -->|success| Token[Authenticated Token] Token --> F This chain is the core of Spring Security’s extensibility — you can plug in any number of authentication mechanisms without touching the filter or the rest of the framework.
Continue reading »CORS: Cross-Origin Requests and Preflight Configuration
What Is CORS? The Same-Origin Policy (SOP) is a browser security rule: JavaScript on app.example.com cannot read responses from api.example.com — different subdomain, different origin. Without this, any website could use a visitor’s authenticated session to silently call other sites on their behalf. CORS (Cross-Origin Resource Sharing) is the mechanism by which a server explicitly relaxes SOP for trusted origins. When a browser sees a cross-origin request, it checks whether the server has granted permission before allowing JavaScript to read the response.
Continue reading »CSRF Protection: How It Works and When to Disable It
What Is a CSRF Attack? Cross-Site Request Forgery (CSRF) tricks an authenticated user’s browser into making an unintended request to your application. The attack: Alice is logged into bank.com — her browser holds a valid session cookie Alice visits evil.com evil.com contains <img src="https://bank.com/transfer?to=attacker&amount=5000"> Alice’s browser fires the request, automatically attaching her bank.com session cookie bank.com receives an authenticated request that Alice never intended to make The attack works because browsers automatically send cookies with cross-origin requests.
Continue reading »Domain Object Security: Access Control Lists (ACLs)
What ACLs Solve Role-based access control answers: “Can this user perform this action?” ACLs answer: “Can this user perform this action on this specific object?” Consider a document management system: Alice owns Document #42 — she can read and edit it Bob is a reviewer on Document #42 — he can read it but not edit Carol has no permission on Document #42 — she gets a 403 This cannot be expressed with roles alone.
Continue reading »Form Login Authentication: From Request to Session
Form Login: The Classic Web Authentication Flow Form login is the traditional authentication mechanism for server-rendered web applications. The user fills in a username and password form, the server verifies credentials, creates a session, and returns a session cookie. All subsequent requests carry that cookie. sequenceDiagram participant Browser participant SSF as Spring Security Filters participant AM as AuthenticationManager participant SS as HTTP Session Store participant Controller Browser->>SSF: GET /dashboard (unauthenticated) SSF->>SS: Save original request (RequestCache) SSF-->>Browser: 302 Redirect to /login Browser->>SSF: GET /login SSF-->>Browser: 200 HTML login page Browser->>SSF: POST /login {username, password} SSF->>AM: authenticate(UsernamePasswordToken) AM-->>SSF: Authentication (success) SSF->>SS: Store SecurityContext in session SSF-->>Browser: 302 Redirect to /dashboard\nSet-Cookie: JSESSIONID=abc123 Browser->>SSF: GET /dashboard (JSESSIONID cookie) SSF->>SS: Load SecurityContext from session SSF->>Controller: Request with authenticated user Controller-->>Browser: 200 Dashboard HTML Minimal Configuration @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .
Continue reading »How Spring Security Works: The Big Picture
Why Spring Security Is Hard to Learn Spring Security is not complex because the concepts are complex. Authentication and authorization are straightforward ideas. Spring Security is hard because it hides its machinery: a request comes in, something happens, an endpoint is secured or not — and without knowing the internal architecture, the behaviour feels magical and the configuration feels arbitrary. This article removes the magic. By the end, you will have the mental model needed to understand every other concept in this series.
Continue reading »HTTP Authorization: Securing Endpoints with requestMatchers
HTTP Authorization: The Last Line of Defense AuthorizationFilter is the last filter in the Spring Security chain. After all authentication filters have run (and either set an Authentication or left it as anonymous), AuthorizationFilter makes the final access decision: allow or deny. The rules you write in authorizeHttpRequests() are evaluated in order, first match wins. flowchart TD Request[HTTP Request] --> Auth[AuthorizationFilter] Auth --> Rules{Evaluate rules\nin order} Rules -->|Rule 1 matches| Decision1{Allowed?
Continue reading »HTTP Basic Authentication and Stateless APIs
What Is HTTP Basic Authentication? HTTP Basic is the simplest authentication scheme defined in the HTTP specification (RFC 7617). The client encodes username:password in Base64 and sends it in the Authorization header with every request: Authorization: Basic YWxpY2U6c2VjcmV0 ↑ Base64("alice:secret") Important: Base64 is encoding, not encryption. Anyone who intercepts the request can decode the credentials instantly. HTTP Basic must only be used over HTTPS. sequenceDiagram participant Client as API Client participant SSF as Spring Security Filters participant AM as AuthenticationManager Client->>SSF: GET /api/data\n(no Authorization header) SSF-->>Client: 401 Unauthorized\nWWW-Authenticate: Basic realm="
Continue reading »JWT Authentication: Stateless Token-Based Security
What Is JWT? JWT (JSON Web Token, RFC 7519) is a compact, URL-safe token format for representing claims between two parties. It is the standard for stateless REST API authentication — the server issues a signed token at login, and the client presents it on every subsequent request. No session, no cookie, no server-side state. JWT Structure A JWT has three Base64URL-encoded parts separated by dots: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGljZSIsInJvbGVzIjpbIlJPTEVfVVNFUiJdfQ.signature Header Payload Signature block-beta columns 3 A["
Continue reading »