<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Spring Security Tutorial on Devops Monk</title><link>https://devops-monk.com/categories/spring-security-tutorial/</link><description>Recent content in Spring Security Tutorial on Devops Monk</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 04 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://devops-monk.com/categories/spring-security-tutorial/index.xml" rel="self" type="application/rss+xml"/><item><title>Actuator Security and Production Hardening</title><link>https://devops-monk.com/tutorials/spring-security/actuator-security-production/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/actuator-security-production/</guid><description>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.</description></item><item><title>AuthenticationManager, AuthenticationProvider, and UserDetailsService</title><link>https://devops-monk.com/tutorials/spring-security/authentication-manager-provider/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/authentication-manager-provider/</guid><description>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&amp;rsquo;s extensibility — you can plug in any number of authentication mechanisms without touching the filter or the rest of the framework.</description></item><item><title>CORS: Cross-Origin Requests and Preflight Configuration</title><link>https://devops-monk.com/tutorials/spring-security/cors-configuration/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/cors-configuration/</guid><description>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&amp;rsquo;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.</description></item><item><title>CSRF Protection: How It Works and When to Disable It</title><link>https://devops-monk.com/tutorials/spring-security/csrf-protection/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/csrf-protection/</guid><description>What Is a CSRF Attack? Cross-Site Request Forgery (CSRF) tricks an authenticated user&amp;rsquo;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 &amp;lt;img src=&amp;quot;https://bank.com/transfer?to=attacker&amp;amp;amount=5000&amp;quot;&amp;gt; Alice&amp;rsquo;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.</description></item><item><title>Domain Object Security: Access Control Lists (ACLs)</title><link>https://devops-monk.com/tutorials/spring-security/domain-object-acl/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/domain-object-acl/</guid><description>What ACLs Solve Role-based access control answers: &amp;ldquo;Can this user perform this action?&amp;rdquo; ACLs answer: &amp;ldquo;Can this user perform this action on this specific object?&amp;rdquo;
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.</description></item><item><title>Form Login Authentication: From Request to Session</title><link>https://devops-monk.com/tutorials/spring-security/form-login/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/form-login/</guid><description>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 .</description></item><item><title>How Spring Security Works: The Big Picture</title><link>https://devops-monk.com/tutorials/spring-security/how-spring-security-works/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/how-spring-security-works/</guid><description>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.</description></item><item><title>HTTP Authorization: Securing Endpoints with requestMatchers</title><link>https://devops-monk.com/tutorials/spring-security/http-authorization/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/http-authorization/</guid><description>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?</description></item><item><title>HTTP Basic Authentication and Stateless APIs</title><link>https://devops-monk.com/tutorials/spring-security/http-basic-authentication/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/http-basic-authentication/</guid><description>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(&amp;#34;alice:secret&amp;#34;) 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="</description></item><item><title>JWT Authentication: Stateless Token-Based Security</title><link>https://devops-monk.com/tutorials/spring-security/jwt-authentication/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/jwt-authentication/</guid><description>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["</description></item><item><title>LDAP Authentication: Enterprise Directory Integration</title><link>https://devops-monk.com/tutorials/spring-security/ldap-authentication/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/ldap-authentication/</guid><description>LDAP in the Enterprise LDAP (Lightweight Directory Access Protocol) is the standard protocol for directory services. Microsoft Active Directory, OpenLDAP, and many other enterprise identity providers use LDAP. If your application must authenticate users from a corporate directory, LDAP integration is the path.
sequenceDiagram participant Client participant SpringSecurity as Spring Security participant LDAP as LDAP / Active Directory Client->>SpringSecurity: POST /login {username, password} SpringSecurity->>LDAP: Bind as service account (manager DN) LDAP-->>SpringSecurity: Bind success SpringSecurity->>LDAP: Search for user:\n(uid=alice,ou=users,dc=example,dc=com) LDAP-->>SpringSecurity: User DN found SpringSecurity->>LDAP: Bind as user (verify password) LDAP-->>SpringSecurity: Bind success = password correct SpringSecurity->>LDAP: Search groups for user LDAP-->>SpringSecurity: Groups: [cn=developers, cn=devops] SpringSecurity->>SpringSecurity: Map groups to roles SpringSecurity-->>Client: Authentication success (ROLE_DEVELOPER, ROLE_DEVOPS) Dependencies &amp;lt;!</description></item><item><title>Method Security: @PreAuthorize, @PostAuthorize, @Secured</title><link>https://devops-monk.com/tutorials/spring-security/method-security/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/method-security/</guid><description>Why Method Security Exists URL-based authorization in authorizeHttpRequests() protects HTTP endpoints, but it has blind spots:
The same service method may be called from multiple controllers, scheduled tasks, or message listeners — none of which pass through the HTTP filter chain Fine-grained rules based on method arguments or return values cannot be expressed as URL patterns Authorization logic spread across a large security config is hard to read alongside the code it protects Method security moves the authorization decision to the method itself.</description></item><item><title>Multi-Factor Authentication (TOTP and WebAuthn)</title><link>https://devops-monk.com/tutorials/spring-security/multi-factor-authentication/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/multi-factor-authentication/</guid><description>Why MFA Matters A password alone is a single point of failure. Phishing, credential stuffing, and password reuse mean that knowing a password is not proof of identity. Multi-factor authentication requires something the user knows (password) and something they have (phone, hardware key) — compromising one factor is no longer sufficient.
TOTP: Time-Based One-Time Passwords TOTP (RFC 6238) generates a 6-digit code that changes every 30 seconds, derived from a shared secret and the current time.</description></item><item><title>OAuth2 Fundamentals: Grant Types and Flows</title><link>https://devops-monk.com/tutorials/spring-security/oauth2-fundamentals/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/oauth2-fundamentals/</guid><description>OAuth2 in One Sentence OAuth2 lets a user grant a third-party application limited access to their account on another service — without giving the third party their password.
Classic example: &amp;ldquo;Sign in with Google.&amp;rdquo; Your app never sees the user&amp;rsquo;s Google password. Google verifies the user&amp;rsquo;s identity and gives your app a token with limited permissions.
The Four OAuth2 Roles flowchart TD RO["**Resource Owner**\nThe user who owns the data\n(e.g. Alice, the Google account owner)"</description></item><item><title>OAuth2 Login: Sign In with Google, GitHub, and Custom Providers</title><link>https://devops-monk.com/tutorials/spring-security/oauth2-login/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/oauth2-login/</guid><description>What OAuth2 Login Does OAuth2LoginConfigurer implements the Authorization Code flow for user authentication. When a user clicks &amp;ldquo;Sign in with Google&amp;rdquo;:
Spring redirects to Google&amp;rsquo;s /authorize endpoint User authenticates on Google and grants consent Google redirects back to your app with a code Spring exchanges the code for tokens (back channel) Spring fetches the user profile from /userinfo Spring creates an OAuth2User and stores it in the SecurityContext Dependencies &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.</description></item><item><title>OAuth2 Resource Server: Protecting APIs with Bearer Tokens</title><link>https://devops-monk.com/tutorials/spring-security/oauth2-resource-server/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/oauth2-resource-server/</guid><description>What Is a Resource Server? In OAuth2, a Resource Server is an API that accepts access tokens and returns protected resources. It doesn&amp;rsquo;t issue tokens — that&amp;rsquo;s the Authorization Server&amp;rsquo;s job. The Resource Server just validates tokens and enforces access control.
flowchart LR Client[API Client\nor SPA/Mobile] -->|"1. POST /token\n{client_id, secret}"| AS[Authorization Server\nGoogle / Okta / Custom] AS -->|"2. access_token"| Client Client -->|"3. GET /api/products\nAuthorization: Bearer {token}"| RS[Your Spring Boot API\nResource Server] RS -->|"</description></item><item><title>Password Encoding: BCrypt, Argon2, and DelegatingPasswordEncoder</title><link>https://devops-monk.com/tutorials/spring-security/password-encoding/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/password-encoding/</guid><description>Why Passwords Must Be Hashed Storing plaintext passwords is a critical security failure. When a database is breached, attackers immediately have every user&amp;rsquo;s password — and because people reuse passwords, those credentials work on other sites too.
Password hashing is not encryption. Encryption is reversible. Hashing is one-way: you can verify a password by hashing it and comparing to the stored hash, but you cannot recover the original password from the hash.</description></item><item><title>Password Management: Registration, Reset, and Migration</title><link>https://devops-monk.com/tutorials/spring-security/password-management/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/password-management/</guid><description>Secure Registration Registration is where passwords enter your system. Get it wrong here and no amount of downstream security saves you.
The Registration Flow User submits form → Validate password strength → Check username/email uniqueness → Encode password with PasswordEncoder → Persist user (disabled) → Send verification email → User clicks link → enable account Registration Endpoint @RestController @RequestMapping(&amp;#34;/auth&amp;#34;) public class RegistrationController { private final UserService userService; private final PasswordEncoder passwordEncoder; @PostMapping(&amp;#34;/register&amp;#34;) public ResponseEntity&amp;lt;Void&amp;gt; register(@Valid @RequestBody RegistrationRequest request) { userService.</description></item><item><title>Reactive Security with Spring WebFlux</title><link>https://devops-monk.com/tutorials/spring-security/reactive-security-webflux/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/reactive-security-webflux/</guid><description>Reactive vs. Servlet Security Spring Security&amp;rsquo;s standard configuration targets Servlet-based applications (Spring MVC). Reactive applications built with Spring WebFlux run on a non-blocking event loop — there is no thread-per-request model, so ThreadLocal-based SecurityContextHolder does not work.
Spring Security provides a parallel reactive stack:
Servlet Reactive SecurityFilterChain SecurityWebFilterChain HttpSecurity ServerHttpSecurity SecurityContextHolder ReactiveSecurityContextHolder UserDetailsService ReactiveUserDetailsService AuthenticationManager ReactiveAuthenticationManager @EnableWebSecurity @EnableWebFluxSecurity @EnableMethodSecurity @EnableReactiveMethodSecurity Dependencies &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-boot-starter-webflux&amp;lt;/artifactId&amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-boot-starter-security&amp;lt;/artifactId&amp;gt; &amp;lt;/dependency&amp;gt; Spring Security auto-configures reactive security when WebFlux is on the classpath.</description></item><item><title>Refresh Tokens and Token Rotation</title><link>https://devops-monk.com/tutorials/spring-security/refresh-tokens/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/refresh-tokens/</guid><description>Why Refresh Tokens? Short-lived access tokens (15–60 minutes) limit the damage if a token is stolen — it expires quickly. But forcing users to log in every hour is terrible UX.
Refresh tokens solve this: a long-lived token (7–30 days) stored securely lets the client silently obtain a new access token when the old one expires. The user stays logged in indefinitely without re-entering credentials.
sequenceDiagram participant Client participant AuthServer as Auth Endpoint participant API as Protected API Client->>AuthServer: POST /api/auth/login AuthServer-->>Client: {accessToken: exp 15min, refreshToken: exp 7d} Note over Client,API: Normal API usage (15 min) Client->>API: GET /api/data\nAuthorization: Bearer {accessToken} API-->>Client: 200 OK Note over Client,API: Access token expires Client->>API: GET /api/data\nAuthorization: Bearer {expiredToken} API-->>Client: 401 Unauthorized Note over Client,API: Silent token refresh Client->>AuthServer: POST /api/auth/refresh\n{refreshToken} AuthServer-->>Client: {newAccessToken, newRefreshToken} Client->>API: GET /api/data\nAuthorization: Bearer {newAccessToken} API-->>Client: 200 OK Token Rotation: Every Refresh Issues a New Refresh Token Token rotation is the critical security mechanism: every time a refresh token is used, the server issues a new refresh token and invalidates the old one.</description></item><item><title>Role-Based Access Control: Roles, Authorities, and Hierarchies</title><link>https://devops-monk.com/tutorials/spring-security/role-based-access-control/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/role-based-access-control/</guid><description>Roles vs. Authorities: The Distinction That Matters Spring Security uses one interface for both roles and authorities: GrantedAuthority. Both are just strings. The difference is convention.
Authority: a fine-grained permission string — user:read, report:export, order:cancel Role: a coarse-grained label that groups authorities — ROLE_ADMIN, ROLE_MANAGER, ROLE_USER The ROLE_ prefix is the only mechanical difference. When you call hasRole(&amp;quot;ADMIN&amp;quot;), Spring Security prepends ROLE_ automatically and checks for ROLE_ADMIN. When you call hasAuthority(&amp;quot;ROLE_ADMIN&amp;quot;) you must include the prefix yourself.</description></item><item><title>Security Headers: CSP, HSTS, Clickjacking Protection</title><link>https://devops-monk.com/tutorials/spring-security/security-headers/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/security-headers/</guid><description>Why Security Headers Matter Security headers tell browsers how to behave when handling your content. They stop entire classes of attacks — XSS, clickjacking, protocol downgrade, information leakage — with a few lines of configuration. They cost nothing at runtime and are one of the highest-value-per-effort security improvements available.
Spring Security&amp;rsquo;s Default Headers Spring Security adds a set of secure headers by default. You do not need any explicit configuration to get them:</description></item><item><title>SecurityContext and Authentication Object</title><link>https://devops-monk.com/tutorials/spring-security/security-context-authentication/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/security-context-authentication/</guid><description>The SecurityContext Is the Source of Truth Every security decision in Spring Security ultimately comes down to one question: &amp;ldquo;What Authentication object is stored in the SecurityContext?&amp;rdquo;
Does the user have ROLE_ADMIN? → check Authentication.getAuthorities() What is the user&amp;rsquo;s ID? → cast Authentication.getPrincipal() to UserDetails Is the user logged in at all? → check Authentication.isAuthenticated() Understanding the SecurityContext and Authentication is not optional — it underlies everything.
The Object Hierarchy classDiagram class SecurityContextHolder { -strategy: SecurityContextHolderStrategy +getContext() SecurityContext +setContext(SecurityContext context) +clearContext() +getContextHolderStrategy() SecurityContextHolderStrategy } class SecurityContext { &lt;> +getAuthentication() Authentication +setAuthentication(Authentication authentication) } class Authentication { &lt;> +getPrincipal() Object +getCredentials() Object +getAuthorities() Collection~GrantedAuthority~ +getDetails() Object +isAuthenticated() boolean +getName() String } class UsernamePasswordAuthenticationToken { +UsernamePasswordAuthenticationToken(principal, credentials) +UsernamePasswordAuthenticationToken(principal, credentials, authorities) } class GrantedAuthority { &lt;> +getAuthority() String } class SimpleGrantedAuthority { -role: String +getAuthority() String } SecurityContextHolder --> SecurityContext SecurityContext --> Authentication Authentication &lt;|.</description></item><item><title>SecurityFilterChain Bean: The Modern Configuration API</title><link>https://devops-monk.com/tutorials/spring-security/security-filter-chain-config/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/security-filter-chain-config/</guid><description>The Modern Configuration Model Spring Security 6.x dropped WebSecurityConfigurerAdapter. The new model uses a SecurityFilterChain @Bean directly. This is not just a syntax change — it&amp;rsquo;s a fundamentally cleaner design:
Old approach New approach Extend WebSecurityConfigurerAdapter @Bean SecurityFilterChain method Override configure(HttpSecurity) Accept HttpSecurity parameter Chain with .and() Lambda DSL — each concern is a separate block One class per application Multiple beans, one per URL namespace Implicit global AuthenticationManager Explicit AuthenticationManager bean // OLD — don&amp;#39;t do this @Configuration public class OldSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.</description></item><item><title>Session Management: Fixation, Concurrency, and Redis Sessions</title><link>https://devops-monk.com/tutorials/spring-security/session-management/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/session-management/</guid><description>How Spring Security Uses Sessions For form login and traditional web applications, Spring Security stores the Authentication object in the HTTP session. On every request, SecurityContextPersistenceFilter (Spring Security 5) or SecurityContextHolderFilter (Spring Security 6) loads the SecurityContext from the session and puts it in the SecurityContextHolder.
For stateless APIs using JWT or OAuth2 Bearer tokens, no session is created — the token is verified on every request.
Session Creation Policy Control when Spring Security creates sessions:</description></item><item><title>Spring Authorization Server: Build Your Own OAuth2 Server</title><link>https://devops-monk.com/tutorials/spring-security/spring-authorization-server/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/spring-authorization-server/</guid><description>What Is Spring Authorization Server? Spring Authorization Server (SAS) is an official Spring project that implements OAuth 2.1 and OpenID Connect 1.0 as a Spring Boot application. It provides a complete authorization server you can host yourself — issuing tokens for your own clients and APIs.
Use it when:
You want SSO across your own microservices You cannot use a hosted provider (Okta, Auth0) due to compliance or cost You need complete control over token format and claims You&amp;rsquo;re building a platform where other apps authenticate against your identity service Architecture flowchart TD SPA[SPA / Mobile App\nOAuth2 Client] -->|Authorization Code + PKCE| SAS Service[Backend Service\nClient Credentials| SAS] SAS[Spring Authorization Server\nIssues tokens] RS1[Your REST API\nResource Server] -->|Validates JWT| SAS RS2[Another API\nResource Server] -->|Validates JWT| SAS SAS -->|Signs tokens with| PK[Private Key\nJWK Set at /.</description></item><item><title>Spring Security Best Practices and Production Checklist</title><link>https://devops-monk.com/tutorials/spring-security/spring-security-best-practices/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/spring-security-best-practices/</guid><description>Using This Reference This is the final article in the Spring Security series. It is a consolidated reference — not a tutorial. Come back to this checklist before every launch and when reviewing a new codebase. Each item links back to the relevant article in the series.
1. Keep Spring Security Updated Security vulnerabilities in Spring Security itself are rare but severe when they occur. A dependency that is one minor version behind can expose known CVEs.</description></item><item><title>Testing Spring Security: @WithMockUser, MockMvc, and SecurityMockMvc</title><link>https://devops-monk.com/tutorials/spring-security/testing-spring-security/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/testing-spring-security/</guid><description>Why Security Tests Are Non-Negotiable A security configuration that is never tested is a security configuration that is probably wrong. URL patterns have subtle ordering rules. Method security annotations are silently ignored if @EnableMethodSecurity is missing. CSRF tokens must be present in the right form. Testing is the only way to know your authorization rules are actually enforced.
Test Dependencies &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-security-test&amp;lt;/artifactId&amp;gt; &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt; &amp;lt;/dependency&amp;gt; &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;spring-boot-starter-test&amp;lt;/artifactId&amp;gt; &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt; &amp;lt;/dependency&amp;gt; @WithMockUser The simplest way to simulate an authenticated user.</description></item><item><title>The Security Filter Chain: Every Filter Explained</title><link>https://devops-monk.com/tutorials/spring-security/security-filter-chain/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/security-filter-chain/</guid><description>Every Filter Has a Job The Spring Security filter chain is not a monolith — it&amp;rsquo;s 15-20 individual filters, each responsible for exactly one concern. Understanding each filter&amp;rsquo;s job means you can:
Know exactly where in the chain a request fails Add your own filter in the right position Remove filters you don&amp;rsquo;t need for performance Debug authentication and authorization problems The Complete Filter Order Spring Security defines a strict ordering for its filters.</description></item><item><title>X.509 Certificate Authentication</title><link>https://devops-monk.com/tutorials/spring-security/x509-certificate-authentication/</link><pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate><guid>https://devops-monk.com/tutorials/spring-security/x509-certificate-authentication/</guid><description>What Is X.509 Authentication? X.509 authentication (also called mutual TLS or mTLS) uses digital certificates instead of passwords. The client presents a certificate during the TLS handshake. The server verifies the certificate against a trusted Certificate Authority (CA) and extracts the user identity from the certificate&amp;rsquo;s Common Name (CN) or Subject Alternative Name (SAN).
sequenceDiagram participant Client as Client (with certificate) participant Server as Spring Boot Server Client->>Server: TLS ClientHello Server->>Client: TLS ServerHello + Server Certificate Server->>Client: CertificateRequest (ask for client cert) Client->>Server: Client Certificate + CertificateVerify Server->>Server: Verify against trusted CA Server->>Server: Extract CN from certificate: "</description></item></channel></rss>