Fixes to Overcome Circular Dependency in Authorization Flow


Fixes to Overcome Circular Dependency in Authorization Flow


We are building a Spring Boot microservices project with multiple services like:

  • user-service (manages user info)
  • merchant-service (manages merchant info)
  • Other services...

 Security Setup

  • All services share a common library that:
             Validates tokens
             Loads user and 
merchant info by calling other services (user-service, merchant-service)

The Problem: Circular Calls

Here’s what’s going wrong:

  • The common library in a service (e.g., merchant-service) calls the user-service to get user info.
  • But user-service also uses the same common library, and it needs merchant info → so it calls back the merchant-service.

This creates a circular REST call between services:

merchant→ user → merchant→ user... 

This can lead to failures or stuck calls.


 Options You Proposed

 Option 1: Exclude endpoints from security

 Pros: Quick fix.

 Cons:

  • Security risk: Unsecured internal endpoints might be accidentally exposed.
  • Makes security logic inconsistent across services.

 Option 2: Use Redis for caching merchant/user info

 How it works:

  • Cache the user/merchant data in Redis.
  • On subsequent calls, common module loads from Redis, avoiding REST calls.

 Pros:

  • Fast
  • Avoids circular calls
  • Good for read-heavy data (e.g., merchant config/user role)

 Cons:

  • Cache invalidation is hard — what if user/merchant is updated?
  • Need proper cache expiry or invalidation strategy
  • Adds operational complexity (maintain Redis cluster)

Recommended when:

  • You have many services relying on shared user/merchant context
  • You can tolerate short-lived stale data or have invalidation hooks


Option 3: Use API Gateway with token translation (Best Option)

 How it works:

  •    All external calls go through a gateway service
  •    Gateway does full security validation using common util
  •    Gateway generates a new internal token (JWT, opaque, etc.)
  •    This token is passed to downstream services
  •    Each downstream service only needs to:

                               Validate internal token

                               Extract merchant/user info without REST calls


 Pros:

  • Avoids circular REST calls entirely
  • Clean separation of concerns (security handled only at gateway)
  • Internal calls are lightweight
  • Easy to track/trace requests from gateway

 Cons:

  • Slightly more complex setup
  • Need to manage 2-token system: external JWT and internal token

Highly Recommended for enterprise-grade microservices

 (especially with 5+ services depending on same context)


Final Recommendation

Option 1  ->  Not recommended->Security loopholes, temp fix only

Option 2 -> Good-> If performance is critical and cache invalidation is manageable 

Option 3 -> Best ->Clean, scalable, secure approach for microservice architectures 


 Bonus Suggestion:

Use Spring Cloud Gateway or Netflix Zuul as your API Gateway, with 'spring-security' and custom 'AuthenticationManager' to handle token translation.


----------------------------------------------------------------------------------------------------------------------


 Quick Recap: What is Option 2?

You store user/merchant data in Redis after login 

Later, all services use Redis to get that data instead of calling user/merchant service again.

Negative Points of Using Redis (Explained Simply)


 1. Stale Data (Old data issue)

Problem: Data in Redis doesn't update automatically if the database changes.

 Example:

  1. User name is '"Alice"' — cached in Redis.
  2. Admin updates her name to '"Alicia"' in the DB.
  3. But Redis still has '"Alice"' unless we manually clear/update the cache.
  4. Services continue showing old name '"Alice"'.

 Result: Users see outdated info — unless you build complex cache refresh logic.


 2. Extra Complexity (More code, more bugs)

 Problem: Now your app must handle:

  •  When to add to Redis 
  •  When to update Redis after DB changes 
  •  When to delete data (expire/evict) 

 Example:

If merchant info changes (e.g., plan, settings), you must:

  •  Detect the change
  •  Update Redis at the right time
  •  Or invalidate Redis key

 Result: More things to maintain = more bugs 


 3. Security Risk (If not handled properly)

Problem: You’re storing sensitive info in Redis (user roles, permissions).

If Redis access is not secure:  Hackers might read/edit merchant/user data from Redis.

Result: Leads to serious data leaks or privilege escalation.


 4. Redis Goes Down = Problems

 Problem: If Redis is unavailable or crashes, services depending on it may:

  •  Fail
  •  Return null/missing user info
  •  Block processing

 Result: Service instability unless you write fallback logic (more work).


 5. Memory Pressure in Redis

Redis stores data in memory (RAM)

If you cache too much (1000s of users/merchant :

  •  Redis uses more memory
  •  Might slow down or crash



Comments

Popular posts from this blog

Database - Topics

02. Spring – Creating spring project clone it with GIT step by step.

01. Steps in SQL Query Execution (MySQL)