What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
This template gives you the modern foundation for a secured Java REST API: Spring Boot acts as an OAuth 2.0 resource server, Keycloak issues OpenID Connect access tokens, PostgreSQL stores application data, and Flyway manages schema changes. The API validates bearer JWTs without querying the application database for every request.
You can run the local infrastructure with Docker Compose, protect CRUD endpoints with scopes or roles, and verify the complete authentication path with Testcontainers.
Architecture
Client
| obtains an access token
v
Keycloak
| Authorization: Bearer JWT
v
Spring Boot API
| validates issuer, signature, expiry and claims
v
PostgreSQL application database
Keycloak is the identity provider and authorization server. Spring Boot is the resource server. PostgreSQL stores business data such as products, projects or orders.
Keep Keycloak’s internal database separate from the application’s database. Sharing one PostgreSQL server is reasonable for local development, but use separate databases, credentials or schemas. Production deployments may warrant separate managed instances.
#1 Best Overall
- Boosts System Performance: 32GB DDR5 RAM laptop memory kit (2x16GB) that operates at 5600MHz, 5200MHz, or 4800MHz to improve multitasking and system responsiveness for smoother performance
- Accelerated gaming performance: Every millisecond gained in fast-paced gameplay counts—power through heavy workloads and benefit from versatile downclocking and higher frame rates
- Optimized DDR5 compatibility: Best for 12th Gen Intel Core and AMD Ryzen 7000 Series processors — Intel XMP 3.0 and AMD EXPO also supported on the same RAM module
- Trusted Micron Quality: Backed by 42 years of memory expertise, this DDR5 RAM is rigorously tested at both component and module levels, ensuring top performance and reliability
- ECC Type = Non-ECC, Form Factor = SODIMM, Pin Count = 262-Pin, PC Speed = PC5-44800, Voltage = 1.1V, Rank And Configuration = 1Rx8
| Requirement | Spring Security capability |
|---|---|
| API receives a bearer token | OAuth2 Resource Server |
| Web application redirects users to Keycloak | OAuth2 Client/Login |
| Backend calls another protected API | OAuth2 Client |
For a bearer-token API, use standard Spring Security OAuth2 Resource Server support rather than older Keycloak-specific Spring adapters. See the Spring Boot OAuth2 documentation and Spring Security OAuth2 documentation.
Project dependencies
Pin a tested Java, Spring Boot, PostgreSQL, Keycloak and Testcontainers version matrix in the repository. Avoid describing the stack as “latest”; compatibility changes over time.
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Add spring-boot-starter-oauth2-client only when the application needs browser login or outbound OAuth2 calls. Optional additions include OpenAPI documentation, Testcontainers’ PostgreSQL and Keycloak modules, and a cache or Redis starter when the application actually needs them.
PostgreSQL and application configuration
spring:
application:
name: secured-api
datasource:
url: ${DB_URL:jdbc:postgresql://localhost:5432/appdb}
username: ${DB_USERNAME:app}
password: ${DB_PASSWORD:app}
jpa:
open-in-view: false
hibernate:
ddl-auto: validate
properties:
hibernate:
format_sql: true
security:
oauth2:
resourceserver:
jwt:
issuer-uri: ${KEYCLOAK_ISSUER_URI:http://localhost:8080/realms/demo}
audiences:
- secured-api
flyway:
enabled: true
The issuer must match the token’s iss claim. Spring Boot uses the issuer metadata and signing-key information to configure JWT validation. Audience validation is separate: a token can come from the correct realm while still being intended for another service. Configure the expected audience when that distinction matters. The emitted audience depends on Keycloak client and protocol-mapper settings.
Use Flyway or Liquibase as the owner of schema changes and keep Hibernate at validate. Never use create or create-drop in production. Keep database credentials in environment variables or a secret manager, configure connection-pool limits, and expose only the actuator endpoints you need.
Rank #2
- A-Tech 16GB RAM Module, DDR4 SO-DIMM 260-Pin, 3200MHz PC4-25600 (PC4-3200AA)
- Non-ECC Unbuffered, JEDEC DDR4 Standard 1.2V Operating Voltage
- Compatible with select Laptop, Notebook, Mini PC, and All-in-One (AIO) systems. Please verify your system's memory type, form factor, and maximum supported capacity before purchasing
- Not compatible with desktop DIMM, non DDR4 memory, or ECC memory types such as RDIMM, LRDIMM, and ECC UDIMM
- Increases available memory capacity to enhance system responsiveness, application performance, and multitasking capabilities.
JPA or JDBC?
JPA is a practical default for aggregate-oriented CRUD applications with repositories and entity relationships. Spring JDBC is often a better choice for SQL-heavy reporting, PostgreSQL-specific queries and data-oriented workflows. Neither removes the need for explicit transactions, indexes, constraints, pagination and query review.
Design PostgreSQL deliberately: choose UUID or numeric identifiers, use appropriate timestamp semantics, add unique and foreign-key constraints, index JSONB only when justified, use stable ordering for pagination, and consider optimistic locking for concurrent updates.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallDocker Compose for local development
Run separate logical databases for the API and Keycloak. Pin image versions that you have tested.
services:
app-db:
image: postgres:<tested-version>
environment:
POSTGRES_DB: appdb
POSTGRES_USER: app
POSTGRES_PASSWORD: app
ports:
- "5432:5432"
volumes:
- app-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
interval: 5s
timeout: 5s
retries: 20
keycloak-db:
image: postgres:<tested-version>
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: keycloak
volumes:
- keycloak-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U keycloak -d keycloak"]
interval: 5s
timeout: 5s
retries: 20
keycloak:
image: quay.io/keycloak/keycloak:<tested-version>
command: start-dev
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://keycloak-db:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: keycloak
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
ports:
- "8080:8080"
depends_on:
keycloak-db:
condition: service_healthy
volumes:
app-db-data:
keycloak-db-data:
This uses start-dev and simple credentials for local work only. Keycloak’s container documentation covers container and PostgreSQL deployment configuration. In production, use HTTPS, a stable hostname, injected secrets, durable storage, backups, health monitoring and a supported deployment strategy. Container startup order also does not guarantee that discovery metadata is ready.
Configure Keycloak
- Start the services with
docker compose up -d app-db keycloak-db keycloak. - Open the Keycloak administration console on port 8080.
- Create a realm named
demo. - Create a client representing the frontend, CLI, mobile app or service that obtains tokens. Do not use one universal client configuration for every caller.
- Create explicit scopes such as
products:readandproducts:write, or create client roles such asadmin. - Create a temporary local test user and assign the required permissions.
For browser applications, use Authorization Code with PKCE and exact redirect URIs and web origins. For machine-to-machine calls, use a confidential client and client credentials. Avoid enabling the password grant as a default. A pure resource server does not need a client secret merely to validate JWTs.
Rank #3
- Boosts System Performance:16GB DDR4 laptop memory that operates at 3200MHz to improve multitasking and system responsiveness for smoother performance
- Easy Installation: Upgrade your laptop RAM with ease—no computer skills required Follow step-by-step how-to guides available at Crucial for a smooth, worry-free installation
- Compatibility Guaranteed: Ensure seamless compatibility with your laptop by using the Crucial System Scanner or Crucial Upgrade Selector—get accurate recommendations for your specific device
- Trusted Micron Quality: Backed by 42 years of memory expertise, this DDR4 RAM is rigorously tested at both component and module levels, ensuring top performance and reliability for your Mac system
- ECC Type = Non-ECC, Form Factor = SODIMM, Pin Count = 260-pin, PC Speed = PC4-25600, Voltage = 1.2V, Rank and Configuration = 1Rx8 or 2Rx8
Realm imports can make local setup reproducible, but never commit real client secrets, administrator credentials or production user data. See the current Keycloak documentation for version-specific configuration.
Recommended Free Tools
Configure Spring Security
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health", "/v3/api-docs/**", "/swagger-ui/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/products/**")
.hasAuthority("SCOPE_products:read")
.requestMatchers(HttpMethod.POST, "/api/products/**")
.hasAuthority("SCOPE_products:write")
.requestMatchers(HttpMethod.DELETE, "/api/products/**")
.hasRole("admin")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
return http.build();
}
}
Disabling CSRF is usually appropriate for a stateless API that authenticates exclusively with bearer tokens in the Authorization header. It is not a universal setting. Cookie- or session-authenticated browser applications should retain and configure CSRF protection; mixed applications need a deliberate design.
Scopes and roles are not interchangeable
Spring Security commonly converts scope or scp claims into authorities such as SCOPE_products:read. Keycloak roles commonly appear under realm_access.roles or resource_access.<client>.roles. They do not automatically become ROLE_... authorities in every configuration.
For realm roles, add an explicit converter:
@Bean
JwtAuthenticationConverter jwtAuthenticationConverter() {
JwtGrantedAuthoritiesConverter scopes = new JwtGrantedAuthoritiesConverter();
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(jwt -> {
Set<GrantedAuthority> authorities = new HashSet<>(scopes.convert(jwt));
Map<String, Object> realmAccess = jwt.getClaim("realm_access");
if (realmAccess != null && realmAccess.get("roles") instanceof Collection<?> roles) {
roles.forEach(role -> authorities.add(
new SimpleGrantedAuthority("ROLE_" + role)));
}
return authorities;
});
return converter;
}
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())))
Choose one policy deliberately: scopes for API permissions, client roles for application-specific roles, realm roles for genuinely realm-wide permissions, groups for organizational membership, and custom claims only where standard claims are insufficient. Always verify the actual access token and ensure the Keycloak claim location matches the Spring authority rule.
Method security
@Configuration
@EnableMethodSecurity
class MethodSecurityConfig { }
@RestController
@RequestMapping("/api/products")
class ProductController {
@GetMapping
@PreAuthorize("hasAuthority('SCOPE_products:read')")
List<ProductResponse> list() { return List.of(); }
@PostMapping
@PreAuthorize("hasAuthority('SCOPE_products:write')")
ResponseEntity<ProductResponse> create(
@Valid @RequestBody CreateProductRequest request) {
return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
URL rules provide perimeter protection; method rules protect operations closer to the service boundary. Neither replaces object-level authorization. For example, a user with a valid write scope may still need a check that the project belongs to the user’s organization. Use the Keycloak subject identifier, sub, as the stable external identity key rather than email, which can change.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #4
- Capacity – Single Module 16GB Speed up to 2666MHz Non-ECC Unbuffered 260-Pin 1.2V SODIMM.
- Specs – PCB Color (Green or Black) and Rank (1Rx8 or 2Rx8) may vary depending on production batch. Performance and quality remain consistent across all Timetec products.
- Compatibility – Designed for selected DDR4 Laptop, Notebook, Mini PCs, and All-In-One systems(AIO) that support 260-Pin SODIMM memory. NOT compatible with Desktop DIMM slots.
- Installation – Plug-and-Play Upgrade, Quick and Easy to Install, no expertise required (please refer to your system's manual for guidelines).
- Warranty – All Timetec products are high-quality and rigorously tested to meet stringent standards. Backed by Timetec Limited Lifetime Warranty and professional technical support based in the United States.
Build and call a protected endpoint
A small resource such as Product is enough to demonstrate the complete path:
GET /api/products authenticated
GET /api/products/{id} authenticated
POST /api/products products:write
PUT /api/products/{id} products:write
DELETE /api/products/{id} admin
GET /actuator/health public
Use a normal controller-service-repository structure, Bean Validation on request DTOs, transactions at service boundaries, consistent error responses and a Flyway migration such as V1__create_products.sql. Keep entity exposure separate from API response models.
Set local variables and start the application:
export DB_URL=jdbc:postgresql://localhost:5432/appdb
export DB_USERNAME=app
export DB_PASSWORD=app
export KEYCLOAK_ISSUER_URI=http://localhost:8080/realms/demo
./mvnw spring-boot:run
PowerShell:
$env:DB_URL="jdbc:postgresql://localhost:5432/appdb"
$env:DB_USERNAME="app"
$env:DB_PASSWORD="app"
$env:KEYCLOAK_ISSUER_URI="http://localhost:8080/realms/demo"
./mvnw spring-boot:run
After migrations run and issuer discovery succeeds, call the API:
curl http://localhost:8081/api/products
-H "Authorization: Bearer $ACCESS_TOKEN"
No token should produce 401 Unauthorized. A valid token without the required scope should produce 403 Forbidden. A valid token with the required authority should succeed.
Free tools Windows power users keep installed
One-click scans. No signup required.
The token request depends on the caller. Prefer Authorization Code with PKCE for user-facing applications, client credentials for service-to-service calls, and device authorization for suitable devices or command-line clients.
Best Value
- 1600MHz (PC3 12800) 204-pin CL11 SODIMM for laptop memory
- Runs at low voltage of 1.35V that enables to effectively decrease hardware power consumption.
- Compatible with MacBook Pro13-inch/15-inch Mid 2012, iMac 21.5-inch Late 2012/ Early/Late 2013
- Backed by a lifetime warranty to promise complete services and technical support.
Testing strategy
Use three layers:
- Unit tests: services, validation, JWT authority conversion and authorization policies.
- Security/MVC tests: missing, malformed, expired and insufficiently privileged tokens.
- Integration tests: the application, real PostgreSQL, migrations and a disposable Keycloak instance.
| Scenario | Expected result |
|---|---|
| No Authorization header | 401 |
| Malformed or expired token | 401 |
| Wrong issuer or signing key | 401 |
| Valid token without permission | 403 |
| Valid read scope on GET | 200 |
| Valid write scope on POST | 201 |
Mocked JWT tests are fast and useful, but they can hide mismatches in Keycloak claim mapping. Include at least one real token flow. Docker’s Spring Boot, Keycloak and Testcontainers guide demonstrates this style of integration.
Troubleshooting
401 despite a seemingly correct token
- Check expiration, clock skew, realm and signing key.
- Confirm the issuer URL exactly matches the token’s
issclaim. - Ensure the API can reach Keycloak metadata and JWK endpoints.
- Check that the client sent an access token, not an ID token.
- Behind a proxy, verify the externally visible hostname and HTTPS configuration.
403 despite a Keycloak role
- The role may be in
realm_access.roleswhile the API checks scopes. - The role may be under
resource_accessfor another client. - The application may expect
ROLE_ADMINwhile the converter emitsadmin. - The role may appear in the console but not in the issued access token.
Hostnames and startup
A host-run application normally uses http://localhost:8080/realms/demo. An application inside Compose usually reaches Keycloak at http://keycloak:8080/realms/demo. Issuer values, browser access and reverse-proxy configuration must remain consistent. Add readiness checks and retry behavior; a running container is not necessarily a ready identity server.
CORS is a browser-origin policy, not authentication. Configure exact frontend origins when needed and avoid wildcard origins with credentials. Do not expose secrets through actuator endpoints or permissive Compose files.
Production hardening
- Use TLS for Keycloak, PostgreSQL and API traffic.
- Configure a stable external Keycloak hostname and proxy settings.
- Inject credentials through a secret manager rather than source control.
- Use separate least-privilege database users and migration permissions.
- Back up both application and Keycloak databases and test restoration.
- Pin dependencies and container images; patch them regularly.
- Validate audience as well as issuer where the trust boundary requires it.
- Redact tokens, passwords and personal data from logs.
- Monitor Keycloak availability, database health, key rotation and API failures.
- Plan revocation, logout, refresh-token handling and key rotation; local JWT validation does not make identity lifecycle concerns disappear.
- Apply rate limiting and protect administrative endpoints.
Docker Compose and start-dev are excellent for a local template, but they are not automatically a production identity architecture. Keycloak is open-source software, yet hosting, backups, monitoring, upgrades and security operations still have real costs.
Keycloak versus managed identity
| Criterion | Keycloak | Managed provider |
|---|---|---|
| Hosting | Team-managed | Vendor-managed |
| Customization | High | Provider-dependent |
| Operational burden | Higher | Lower |
| Control of identity data | Greater | Subject to provider and region |
| Local development | Convenient with Docker | May require a remote tenant |
Keycloak suits teams that need self-hosting, realm customization or protocol flexibility and can operate security-critical infrastructure. A managed provider may be better when minimizing identity operations is more important than control. Compare current product terms, pricing, quotas and regional availability before choosing.
JWT versus opaque tokens
JWT validation is usually efficient because the API validates a signed token locally using public keys. Opaque-token introspection lets the authorization server make a live validation decision but adds a network dependency. Both approaches are supported by Spring Security. JWTs still require deliberate revocation, expiry, key rotation and logout policies.
Quick Recap
Useful official references
- Spring Initializr
- Spring Boot OAuth2 configuration
- Spring Security OAuth2 resource server
- Spring Security JWT validation
- Keycloak containers
- Keycloak documentation
- Docker Testcontainers example
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errors

