On this page
Overview
Spring Security is a framework for adding authentication and access control to Spring applications. Its filter chain processes requests and lets an application express who may use each surface.
Features and best fit
Based on official documentation; not hands-on tested · Content checked:
Key features
Authenticate HTTP requests and authorize access by path or method
Spring Security processes servlet requests through a filter chain and stores authentication in a SecurityContext. Applications can combine HTTP Basic, form login, OAuth 2.0, and other authentication mechanisms with authorization rules for URLs and methods.
Best fit
Fits Spring Boot services that need explicit public and protected surfaces
A service can declare public endpoints beside endpoints that require a signed-in user, making the framework useful for business APIs and administrative applications. A small in-memory user verifies the request flow before integration with an organizational identity provider or durable user store.
Before adoption
Choose authentication, CSRF, session, and identity storage policies for the application
Adding the dependency does not complete a production security design. Browser and API behavior, CSRF protection, session policy, password storage, and management of keys or client secrets remain application decisions. The cited Spring Boot 4.1.1 line requires Java 17 or later; the Spring Security repository is Apache-2.0.
Official sources
- [1]Spring Security README at commit 1b17ecd(2026-10-04)
- [2]Spring Security 7.1.1 release(2026-10-04)
- [3]Spring Security servlet architecture reference(2026-10-04)
- [4]Spring Security username/password reference(2026-10-04)
- [5]Spring Boot 4.1.1 release(2026-10-04)
- [6]Spring Boot system requirements(2026-10-04)
- [7]Spring Security Apache License at commit 1b17ecd(2026-10-04)
- [8]Spring Security GitHub repository metadata(2026-10-04)
- [9]Spring Boot 4.1 Maven plugin executable archive packaging(2026-10-04)
Supplemental curator note
Spring Security is a strong fit when a Spring team wants public and protected surfaces expressed in application configuration. Use the localhost in-memory user only to verify the request flow, then design identity integration, password storage, CSRF protection, and session policy for production.
Try it in 3 steps
- 1
Create a minimal Spring Boot 4.1.1 application
Requires Java 17 or later, Maven 3.6.3 or later, Python 3, and curl. It creates public and protected routes in a temporary directory. demo/demo is a localhost-only demonstration credential.
spring_demo_dir=$(mktemp -d "${TMPDIR:-/tmp}/spring-security-demo.XXXXXX") && cd "$spring_demo_dir" && printf '%s ' '<project xmlns="http://maven.apache.org/POM/4.0.0">' '<modelVersion>4.0.0</modelVersion>' '<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>4.1.1</version><relativePath/></parent>' '<groupId>demo</groupId><artifactId>security-demo</artifactId><version>0.0.1</version>' '<properties><java.version>17</java.version></properties>' '<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency></dependencies>' '<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>' '</project>' > pom.xml - 2
Create the Java source and build
In the same directory, create both routes and let the Spring Boot Maven Plugin repackage the build as an executable JAR. demo/demo is a localhost-only demonstration credential.
mkdir -p src/main/java/demo && printf '%s ' 'package demo;' 'import org.springframework.boot.*;import org.springframework.boot.autoconfigure.*;import org.springframework.context.annotation.*;import org.springframework.security.config.annotation.web.builders.*;import org.springframework.security.core.userdetails.*;import org.springframework.security.provisioning.*;import org.springframework.security.web.*;import org.springframework.web.bind.annotation.*;' '@SpringBootApplication @RestController public class DemoApplication{' '@GetMapping("/public") String a(){return "public";} @GetMapping("/private") String b(){return "private";}' '@Bean SecurityFilterChain s(HttpSecurity h)throws Exception{return h.authorizeHttpRequests(a->a.requestMatchers("/public").permitAll().anyRequest().authenticated()).httpBasic(b->{}).build();}' '@Bean UserDetailsService u(){return new InMemoryUserDetailsManager(User.withUsername("demo").password("{noop}demo").roles("USER").build());}' 'public static void main(String[]a){SpringApplication.run(DemoApplication.class,a);}}' > src/main/java/demo/DemoApplication.java && mvn -q -DskipTests package - 3
Verify the authentication flow on localhost
Launch the executable JAR directly on an available loopback port and own that PID. After public 200, unauthenticated 401, and authenticated 200 checks, kill and wait for it and verify the port is closed. The isolated subshell preserves the caller trap.
( set -eu; port=$(python3 -c 'import socket; s=socket.socket(); s.bind(("127.0.0.1",0)); print(s.getsockname()[1]); s.close()'); app_pid=''; cleanup(){ if [ -n "$app_pid" ]; then kill "$app_pid" 2>/dev/null || true; wait "$app_pid" 2>/dev/null || true; fi; }; trap cleanup EXIT HUP INT TERM; java -jar target/security-demo-0.0.1.jar --server.address=127.0.0.1 --server.port="$port" > app.log 2>&1 & app_pid=$!; ready=0; i=0; while [ "$i" -lt 40 ]; do if curl --silent --max-time 1 "http://127.0.0.1:$port/public" > public.txt 2>/dev/null; then ready=1; break; fi; i=$((i+1)); sleep 0.25; done; [ "$ready" -eq 1 ]; [ "$(cat public.txt)" = public ]; code=$(curl --silent --output private-unauth.txt --write-out '%{http_code}' --max-time 2 "http://127.0.0.1:$port/private"); [ "$code" = 401 ]; [ "$(curl --silent --max-time 2 --user demo:demo "http://127.0.0.1:$port/private")" = private ]; cleanup; app_pid=''; python3 -c 'import errno,socket,sys; s=socket.socket(); s.settimeout(1); r=s.connect_ex(("127.0.0.1",int(sys.argv[1]))); raise SystemExit(0 if r==errno.ECONNREFUSED else 1)' "$port"; trap - EXIT HUP INT TERM; printf 'public=200 private_unauth=%s private_auth=200 stopped=true ' "$code" )
Growth
Growth trends · Last 30 days
9,638 Stars
Trend data is still being collected.
Development activity
Last 90 days · weekly
- Commits (last 30 days)
- 101
- Open PRs
- 229
Development activity is still being collected.
Built with
Categories and tags
Categories
GitHub data
GitHub dataView detailed GitHub data
GitHub Topics
- java
- security
- spring
- spring-framework
- framework
- Stars
- 9,638
- Forks
- 6,363
- Watchers
- 415
- Open issues
- 1,278
- Contributors
- 392
- Owner type
- Organization
- Primary language
- Java
- License
- Apache-2.0
- Repository last updated
- Oct 2, 2026
Related information
Write a related articleShare a guide or use case for this OSS in Markdown. Articles are published after administrator approval.
Explore next
- SuperTokens Core15,333 Stars
2 shared tag(s) · 1 shared category(s) · Same language
Self-host the authentication, session, and user-data core that frontend and backend SDKs call over HTTP
Java - Auth.js28,368 Stars
2 shared tag(s) · 1 shared category(s)
Compose OAuth/OIDC, passwordless, WebAuthn, and stateless or database-backed sessions from packages built around standard Web APIs
TypeScript - Devise24,355 Stars
2 shared tag(s) · 1 shared category(s)
compose Rails authentication workflows from modular features on top of Warden
Ruby - Cosmos Server6,174 Stars
2 shared tag(s) · 1 shared category(s)
manage home-server apps, access, protection, and backups together
Go - Passbolt6,147 Stars
2 shared tag(s) · 1 shared category(s)
share and audit team credentials with user-owned keys and end-to-end encryption
PHP - SPIRE2,569 Stars
2 shared tag(s) · 1 shared category(s)
attest running workloads and issue short-lived SVID credentials bound to SPIFFE identities
Go
Report incorrect information
Tell us if any listing information is incorrect or outdated.