OAuth Token Propagation Patterns

# OAuth Token Propagation Patterns in Microservices

## 1. Token Relay Pattern

### Description
Forwards the original OAuth token through service chains while maintaining the original user context.

### Implementation
```mermaid
sequenceDiagram
    participant C as Client
    participant AG as API Gateway
    participant S1 as Service 1
    participant S2 as Service 2
    
    C->>AG: Request + OAuth Token
    AG->>AG: Validate Token
    AG->>S1: Forward Request + Token
    S1->>S2: Forward Request + Original Token
    S2->>S2: Validate Token
```

### Considerations
- **Pros:**
  - Simple implementation
  - Maintains user context
  - Easy to audit
- **Cons:**
  - Token size overhead
  - Potential scope exposure
  - Limited granular control

### Code Example
```java
public class TokenRelayInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, 
            ClientHttpRequestExecution execution) {
        
        String token = SecurityContextHolder.getContext()
            .getAuthentication()
            .getCredentials()
            .toString();
            
        request.getHeaders().add("Authorization", "Bearer " + token);
        request.getHeaders().add("X-Original-User-Context", getUserContext());
        
        return execution.execute(request, body);
    }
}
```

## 2. Token Exchange Pattern

### Description
Exchanges the original token for service-specific tokens with limited scope.

### Implementation
```mermaid
sequenceDiagram
    participant C as Client
    participant AG as API Gateway
    participant STS as Security Token Service
    participant S1 as Service 1
    participant S2 as Service 2
    
    C->>AG: Request + OAuth Token
    AG->>STS: Exchange Token Request
    STS->>AG: Service-Specific Token
    AG->>S1: Request + New Token
    S1->>STS: Exchange Token
    STS->>S1: Service-Specific Token
    S1->>S2: Request + New Token
```

### Considerations
- **Pros:**
  - Fine-grained access control
  - Reduced token size
  - Better security isolation
- **Cons:**
  - Additional complexity
  - Higher latency
  - More infrastructure needed

### Code Example
```java
public class TokenExchangeService {
    public String exchangeToken(String originalToken, String targetService) {
        TokenExchangeRequest request = TokenExchangeRequest.builder()
            .subjectToken(originalToken)
            .targetService(targetService)
            .build();
            
        return securityTokenService.exchange(request);
    }
}
```

## 3. Token Cache Pattern

### Description
Implements caching mechanisms for token validation and exchange results.

### Implementation
```mermaid
sequenceDiagram
    participant S as Service
    participant C as Cache
    participant V as Token Validator
    
    S->>C: Check Token
    alt Token in Cache
        C->>S: Return Cached Result
    else Token Not in Cache
        C->>V: Validate Token
        V->>C: Store Result
        C->>S: Return Result
    end
```

### Code Example
```java
public class TokenValidationCache {
    private Cache<String, TokenValidation> validationCache;
    
    public TokenValidation validateToken(String token) {
        return validationCache.get(token, key -> {
            TokenValidation validation = tokenValidator.validate(key);
            if (validation.isValid()) {
                validationCache.put(key, validation, 
                    validation.getTimeToLive());
            }
            return validation;
        });
    }
}
```

## 4. Circuit Breaker Pattern

### Description
Implements failure handling for token validation and exchange services.

### Implementation
```mermaid
sequenceDiagram
    participant S as Service
    participant CB as Circuit Breaker
    participant TS as Token Service
    
    S->>CB: Token Request
    alt Circuit Closed
        CB->>TS: Forward Request
        TS->>CB: Response
        CB->>S: Return Response
    else Circuit Open
        CB->>S: Return Fallback
    end
```

### Code Example
```java
public class TokenServiceCircuitBreaker {
    private CircuitBreaker circuitBreaker;
    
    public TokenValidation validateWithCircuitBreaker(String token) {
        return circuitBreaker.run(
            () -> tokenService.validate(token),
            throwable -> handleFailure(token)
        );
    }
    
    private TokenValidation handleFailure(String token) {
        // Implement fallback strategy
        return TokenValidation.fallback(token);
    }
}
```

## 5. Decorator Pattern for Token Enhancement

### Description
Adds additional context or claims to tokens as they pass through services.

### Implementation
```mermaid
sequenceDiagram
    participant S1 as Service 1
    participant TD as Token Decorator
    participant S2 as Service 2
    
    S1->>TD: Original Token
    TD->>TD: Add Context
    TD->>S2: Enhanced Token
```

### Code Example
```java
public class TokenEnhancerDecorator implements TokenEnhancer {
    private final TokenEnhancer delegate;
    
    public OAuth2AccessToken enhance(OAuth2AccessToken token, 
            OAuth2Authentication auth) {
        
        token = delegate.enhance(token, auth);
        
        Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("service_context", getServiceContext());
        ((DefaultOAuth2AccessToken) token)
            .setAdditionalInformation(additionalInfo);
            
        return token;
    }
}
```

## 6. Observer Pattern for Token Events

### Description
Implements event-based handling of token lifecycle events.

### Implementation
```mermaid
sequenceDiagram
    participant TS as Token Service
    participant P as Publisher
    participant S1 as Subscriber 1
    participant S2 as Subscriber 2
    
    TS->>P: Token Event
    P->>S1: Notify
    P->>S2: Notify
```

### Code Example
```java
public class TokenEventPublisher {
    private List<TokenEventSubscriber> subscribers = new ArrayList<>();
    
    public void publishTokenEvent(TokenEvent event) {
        for (TokenEventSubscriber subscriber : subscribers) {
            subscriber.onTokenEvent(event);
        }
    }
    
    public void subscribe(TokenEventSubscriber subscriber) {
        subscribers.add(subscriber);
    }
}
```

## Best Practices for Pattern Implementation

1. **Combination of Patterns**
   - Use Token Relay for simple flows
   - Implement Token Exchange for complex scenarios
   - Always include Circuit Breaker for resilience
   - Cache validation results where appropriate

2. **Security Considerations**
   - Implement proper token validation at each service
   - Use secure communication channels
   - Implement proper logging and monitoring
   - Regular security audits

3. **Performance Optimization**
   - Implement efficient caching strategies
   - Use asynchronous token validation where possible
   - Optimize token size and content
   - Implement proper timeout handling

4. **Monitoring and Maintenance**
   - Monitor pattern effectiveness
   - Regular pattern review and updates
   - Implement proper logging
   - Set up alerts for pattern failures

Comments

Popular posts from this blog

AWS S3 MRAP

SLO Compliance