The Future of Security: AI-Driven Anomaly Detection with Spring AI
Writing
SECURITY
February 23, 20263 min read

The Future of Security: AI-Driven Anomaly Detection with Spring AI

Move from static rules to dynamic behavioral analysis. Learn how to intercept Spring Security Lifecycle events and feed them into a local LLM or Vector DB to detect account takeover attempts in real-time.

Spring BootSpring AISecurityMachine LearningInnovation

Static rules ("Block after 3 failed attempts") are necessary, but they are predictable. Sophisticated attackers know these rules. They rotate IPs. They sleep between attempts. They use valid credentials purchased from the dark web (Credential Stuffing).

To catch these, we need Behavioral Analysis. We need a system that has "intuition."

In this guide, we will build a "Risk Engine" using Spring Security Events and Spring AI. It sounds like Science Fiction, but with the tools we have today, it's surprisingly accessible.

The Concept

  1. Intercept: Listen for every login (Success or Failure).
  2. Enrich: Add context (GeoIP, Device Fingerprint, Time of Day).
  3. Analyze: Ask an AI model: "Given this user usually logs in from London on a Mac, is this login from a Linux server in Panama suspicious?"
  4. React: If Risk > 80, revoke session or trigger MFA.
Risk Engine Flow

Step 1: Listening to Events

Spring Security publishes events automatically. We just need to catch them.

@Component
public class AuthEventListener {
 
    private final RiskAnalysisService riskService;
 
    public AuthEventListener(RiskAnalysisService riskService) {
        this.riskService = riskService;
    }
 
    @EventListener
    @Async // Crucial: Don't block the login thread!
    public void onSuccess(AuthenticationSuccessEvent event) {
        Authentication auth = event.getAuthentication();
        WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails();
        
        LoginContext ctx = new LoginContext(
            auth.getName(),
            details.getRemoteAddress(),
            LocalDateTime.now()
        );
        
        riskService.analyze(ctx);
    }
    
    @EventListener
    @Async
    public void onFailure(AbstractAuthenticationFailureEvent event) {
        // Track brute force patterns
    }
}

Step 2: The Spring AI Risk Engine

This is where the magic happens. We construct a prompt for the LLM.

@Service
public class RiskAnalysisService {
 
    private final ChatClient chatClient;
    private final UserHistoryRepository historyRepo;
 
    public RiskAnalysisService(ChatClient.Builder builder, UserHistoryRepository repo) {
        this.chatClient = builder.build();
        this.historyRepo = repo;
    }
 
    public void analyze(LoginContext ctx) {
        // 1. Fetch historical baseline
        List<LoginEvent> distinctHistory = historyRepo.findRecentDistinctLogins(ctx.username());
        
        // 2. Construct Prompt
        String prompt = """
            You are a security analyst. 
            User '%s' is attempting to login from IP %s.
            
            Their recent history includes: %s.
            
            Analyze the probability of account takeover.
            Return ONLY a JSON object: {"riskScore": 0-100, "reason": "..."}
        """.formatted(ctx.username(), ctx.ip(), distinctHistory);
 
        // 3. Call AI (Ollama/OpenAI)
        String response = chatClient.prompt(prompt).call().content();
        
        handleRiskDecision(response, ctx.username());
    }
}

Step 3: Taking Action

If the AI returns a high risk score, we can't block the login (it already happened), but we can kill the session immediately.

private void handleRiskDecision(String jsonResponse, String username) {
    RiskAssessment assessment = parse(jsonResponse);
    
    if (assessment.score > 80) {
        log.warn("HIGH RISK LOGIN DETECTED: {}", assessment.reason);
        
        // Revoke all sessions for this user
        sessionRegistry.getAllSessions(username, false)
            .forEach(SessionInformation::expireNow);
            
        // Trigger Email Alert
        notificationService.sendSecurityAlert(username, assessment.reason);
    }
}

Vector Databases for Scale

Passing raw text history to an LLM context window is expensive. For production, you would use Vector Search.

  1. Store login metadata embeddings in pgvector or Weaviate.
  2. When a user logs in, embed the current context.
  3. Query distance to previous logins.
  4. If distance is large (Vector Anomaly), flag it.

Spring AI supports VectorStore interfaces exactly for this purpose.

Conclusion

By merging the event-driven architecture of Spring Security with the probabilistic reasoning of Spring AI, we move from "Rules" to "Intuition".

This allows us to catch novel attacks that static IF-statements would miss. And honestly? It's just really cool to build.

Frequently Asked Questions

Can I use AI for security without sending data to OpenAI?

Absolutetly. You can use local LLMs (like Llama 3 via Ollama) or simpler anomaly detection algorithms (Isolation Forest) directly within your Java application to keep sensitive auth logs private.

What is an AuthenticationSuccessEvent?

It is an ApplicationEvent published by Spring Security immediately after a user successfully logs in. It contains the UserDetails, IP address, and Session ID, making it the perfect hook for auditing.

Is this slow?

Behavioral analysis should almost always happen asynchronously. You don't want to block the user's login while the AI thinks. We use `@Async` event listeners to process risk scores in the background.

Rabinarayan Patra

Rabinarayan Patra

SDE II at Amazon. Previously at ThoughtClan Technologies building systems that processed 700M+ daily transactions. I write about Java, Spring Boot, microservices, and the things I figure out along the way. More about me →

X (Twitter)LinkedIn

Stay in the loop

Get the latest articles on system design, frontend & backend development, and emerging tech trends — straight to your inbox. No spam.