- Published on
8 - Spring Security tutorial part three
- Authors

- Name
- Samreach YAN
Spring Security Masterclass - Part 3: Enterprise-Grade Security Patterns
Table of Contents
- Domain-Driven Security
- Zero Trust Architecture
- Policy-Based Access Control
- Security Event Streaming
- Distributed Session Management
- Secret Rotation Automation
- Security as Code
- Chaos Engineering for Security
- Compliance Automation
- Emerging Trends
1. Domain-Driven Security
Domain-Driven Security aligns security policies with business domains, ensuring access control reflects business logic.
Best Practices
- Model security around domain entities.
- Use domain-specific roles and permissions.
- Leverage Spring Security’s
@PreAuthorizefor domain logic.
Example: Securing a Book Entity
Create a domain model and secure it based on user roles.
// Book.java
package com.example.demo.model;
public class Book {
private Long id;
private String title;
private String author;
private String owner;
public Book(Long id, String title, String author, String owner) {
this.id = id;
this.title = title;
this.author = author;
this.owner = owner;
}
public Long getId() { return id; }
public String getTitle() { return title; }
public String getAuthor() { return author; }
public String getOwner() { return owner; }
}
// BookService.java
package com.example.demo.service;
import com.example.demo.model.Book;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@Service
public class BookService {
@PreAuthorize("hasRole('ROLE_ADMIN') or #book.owner == authentication.name")
public Book updateBook(Book book) {
// Simulate update logic
return book;
}
}
// SecurityConfig.java
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin();
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
var user = User.withUsername("user")
.password("{noop}password")
.roles("USER")
.build();
var admin = User.withUsername("admin")
.password("{noop}password")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
Tutorial
- Baeldung: Spring Security Expressions - Learn
@PreAuthorizeand SpEL. - Spring Docs: Method Security - Official guide for method-level security.
2. Zero Trust Architecture
Zero Trust assumes no trust, requiring continuous verification of users and devices.
Best Practices
- Enforce least privilege.
- Use JWT for stateless authentication.
- Implement mutual TLS for service-to-service communication.
Example: JWT-Based Zero Trust
Secure APIs with JWT and verify every request.
// SecurityConfig.java (Updated)
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt()
);
return http.build();
}
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri("https://example.com/.well-known/jwks.json").build();
}
}
Tutorial
- Okta: Zero Trust with Spring Boot - Guide on JWT and Zero Trust.
- Spring Security OAuth2 Docs - Official resource for OAuth2 integration.
3. Policy-Based Access Control
Policy-Based Access Control (PBAC) uses dynamic policies to manage access.
Best Practices
- Use Open Policy Agent (OPA) or Spring Security ACL.
- Define policies in a centralized repository.
- Evaluate policies at runtime.
Example: Spring Security ACL
Implement ACL to manage fine-grained permissions.
// AclConfig.java
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class AclConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin();
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
var user = User.withUsername("user")
.password("{noop}password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public MutableAclService aclService() {
return new org.springframework.security.acls.jdbc.JdbcMutableAclService(
dataSource(), lookupStrategy(), aclCache());
}
@Bean
public void configureAcl(MutableAclService aclService) {
MutableAcl acl = aclService.createAcl(new ObjectIdentityImpl(Book.class, 1L));
acl.insertAce(0, BasePermission.READ, new PrincipalSid("user"), true);
aclService.updateAcl(acl);
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:org/springframework/security/acl/schema.sql")
.build();
}
@Bean
public AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
@Bean
public EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(
EhCacheFactoryBean().getObject(),
permissionGrantingStrategy(),
aclAuthorizationStrategy()
);
}
@Bean
public EhCacheFactoryBean ehCacheFactoryBean() {
EhCacheFactoryBean factory = new EhCacheFactoryBean();
factory.setCacheManager(cacheManager().getObject());
factory.setCacheName("aclCache");
return factory;
}
@Bean
public CacheManager cacheManager() {
return new EhCacheManagerFactoryBean().getObject();
}
@Bean
public LookupStrategy lookupStrategy() {
return new BasicLookupStrategy(dataSource(), aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger());
}
@Bean
public PermissionGrantingStrategy permissionGrantingStrategy() {
return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
}
}
Tutorial
- Baeldung: Spring Security ACL - Detailed ACL setup guide.
- Open Policy Agent Docs - Learn OPA for policy management.
4. Security Event Streaming
Stream security events for real-time monitoring and analysis.
Best Practices
- Use Kafka or RabbitMQ for event streaming.
- Log events in a structured format (e.g., JSON).
- Integrate with SIEM tools.
Example: Kafka for Security Events
Publish security events to Kafka.
// SecurityEvent.java
package com.example.demo.model;
public class SecurityEvent {
private String eventType;
private String username;
private long timestamp;
public SecurityEvent(String eventType, String username, long timestamp) {
this.eventType = eventType;
this.username = username;
this.timestamp = timestamp;
}
public String getEventType() { return eventType; }
public String getUsername() { return username; }
public long getTimestamp() { return timestamp; }
}
// SecurityEventProducer.java
package com.example.demo.service;
import com.example.demo.model.SecurityEvent;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
@Service
public class SecurityEventProducer {
private final KafkaTemplate<String, SecurityEvent> kafkaTemplate;
public SecurityEventProducer(KafkaTemplate<String, SecurityEvent> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
public void sendEvent(SecurityEvent event) {
kafkaTemplate.send("security-events", event);
}
}
// KafkaConfig.java
package com.example.demo.config;
import com.example.demo.model.SecurityEvent;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.support.serializer.JsonSerializer;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class KafkaConfig {
@Bean
public ProducerFactory<String, SecurityEvent> producerFactory() {
Map<String, Object> configProps = new HashMap<>();
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
return new DefaultKafkaProducerFactory<>(configProps);
}
@Bean
public KafkaTemplate<String, SecurityEvent> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
}
Tutorial
- Spring Kafka Docs - Official guide for Kafka integration.
- Confluent: Kafka Security - Learn Kafka event streaming.
5. Distributed Session Management
Manage sessions across distributed systems using Redis.
Best Practices
- Use Spring Session with Redis.
- Set session timeouts.
- Encrypt session data.
Example: Spring Session with Redis
Store sessions in Redis.
// RedisConfig.java
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
@Configuration
@EnableRedisHttpSession
public class RedisConfig {
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
public HeaderHttpSessionIdResolver sessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
}
Tutorial
- Spring Session Docs - Official guide for Spring Session.
- Baeldung: Spring Session with Redis - Step-by-step setup.
6. Secret Rotation Automation
Automate secret rotation using Spring Cloud Vault.
Best Practices
- Use Vault for secret management.
- Rotate secrets periodically.
- Avoid hardcoding secrets.
Example: Spring Cloud Vault
Access secrets from Vault.
// VaultConfig.java
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.vault.authentication.ClientAuthentication;
import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.config.AbstractVaultConfiguration;
@Configuration
public class VaultConfig extends AbstractVaultConfiguration {
@Override
public VaultEndpoint vaultEndpoint() {
return VaultEndpoint.create("localhost", 8200);
}
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication("my-token");
}
}
// SecretService.java
package com.example.demo.service;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.stereotype.Service;
@Service
public class SecretService {
private final VaultTemplate vaultTemplate;
public SecretService(VaultTemplate vaultTemplate) {
this.vaultTemplate = vaultTemplate;
}
public String getSecret(String path) {
return vaultTemplate.read(path).getData().get("value").toString();
}
}
Tutorial
- Spring Cloud Vault Docs - Official guide for Vault integration.
- HashiCorp Vault Docs - Learn secret rotation.
7. Security as Code
Define security policies as code using Spring Security DSL.
Best Practices
- Use infrastructure as code (IaC) for security.
- Version control security configurations.
- Automate security testing.
Example: Security DSL
Define security rules programmatically.
// SecurityConfig.java (Updated)
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasRole("USER")
.anyRequest().authenticated()
)
.formLogin();
return http.build();
}
}
Tutorial
- Spring Security DSL Docs - Official guide for DSL.
- Baeldung: Security as Code - Practical examples.
8. Chaos Engineering for Security
Test security resilience using chaos engineering.
Best Practices
- Simulate attacks (e.g., DDoS, SQL injection).
- Use tools like Chaos Monkey.
- Monitor system behavior under stress.
Example: Chaos Monkey for Spring Boot
Integrate Chaos Monkey to simulate failures.
// ChaosMonkeyConfig.java
package com.example.demo.config;
import com.chaosmonkey.spring.boot.ChaosMonkey;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
public class ChaosMonkeyConfig {
@Bean
public ChaosMonkey chaosMonkey() {
return new ChaosMonkey();
}
}
Tutorial
- Chaos Monkey for Spring Boot Docs - Official guide.
- Netflix: Chaos Engineering - Learn chaos principles.
9. Compliance Automation
Automate compliance checks using Spring Boot Actuator.
Best Practices
- Expose compliance endpoints.
- Integrate with compliance tools (e.g., OWASP ZAP).
- Schedule automated audits.
Example: Actuator for Compliance
Expose health and metrics endpoints.
// ActuatorConfig.java
package com.example.demo.config;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class ActuatorConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR")
.anyRequest().authenticated()
)
.formLogin();
return http.build();
}
}
Tutorial
- Spring Boot Actuator Docs - Official guide for Actuator.
- Baeldung: Actuator Security - Secure Actuator endpoints.
10. Emerging Trends
Explore trends like AI-driven security and quantum-resistant cryptography.
Best Practices
- Monitor OWASP Top Ten for new threats.
- Experiment with AI for threat detection.
- Prepare for quantum-resistant algorithms.
Example: AI-Driven Threat Detection
Use a simple ML model to detect anomalies.
// AnomalyDetector.java
package com.example.demo.service;
import org.springframework.stereotype.Service;
@Service
public class AnomalyDetector {
public boolean detectAnomaly(String eventData) {
// Simulate ML model
return eventData.contains("suspicious");
}
}
Tutorial
- OWASP Top Ten - Stay updated on threats.
- Google: AI Security - Learn AI-driven security.
Getting Started
- Set Up Spring Boot Project:
- Use Spring Initializr (https://start.spring.io).
- Add dependencies: Spring Security, Spring Boot Starter Web, Spring Kafka, Spring Session, Spring Cloud Vault, Spring Boot Actuator.
- Run Examples:
- Clone the code from this tutorial.
- Configure dependencies (e.g., Kafka, Redis, Vault).
- Run with
mvn spring-boot:run.
- Learn More:
- Spring Security Docs: Comprehensive guide.
- Baeldung: Practical tutorials.
- YouTube: Spring Security Tutorials - Visual learning.
Best Practices Summary
- Use domain-driven roles and policies.
- Implement Zero Trust with JWT and mTLS.
- Centralize policies with OPA or ACL.
- Stream events for real-time monitoring.
- Manage sessions with Redis.
- Automate secret rotation with Vault.
- Define security as code.
- Test resilience with chaos engineering.
- Automate compliance with Actuator.
- Stay updated on emerging trends.
This tutorial provides a complete, working foundation for advanced Spring Security. Explore each topic further with the recommended resources.