Why Token Pass‑Through Fails and How to Build Secure Unified Auth in Microservices

This article examines the pitfalls of token pass‑through authentication in microservices, proposes explicit userId parameter passing, compares unified auth approaches using Spring Cloud Gateway with Feign or Dubbo, and explores non‑unified alternatives, including K8s Ingress integration and practical code examples.

Java High-Performance Architecture
Java High-Performance Architecture
Java High-Performance Architecture
Why Token Pass‑Through Fails and How to Build Secure Unified Auth in Microservices

1. Token

1.1 Token Pass‑Through (Not Recommended)

When first learning microservices, many online solutions suggest passing the Token for authentication. This approach lets each microservice obtain the current user information, which may be convenient but is a poor design.

Reason 1: Internal and external APIs become mixed and hard to distinguish.

Reason 2: Internal microservice APIs should be stateless to ensure atomicity and improve code reuse.

In other words, Service B should not need to know whether the request is authenticated; the first service in the routing layer should validate the token and pass necessary parameters downstream. Consider these scenarios:

User signs in and gains points.

Admin manually adds points to a user.

Distributed scheduler batch adds points.

If the points service only provides an API that adds points based on the current logged‑in user ID, scenario 2 would require a separate API because the logged‑in entity is an admin, not the target user, reducing code reuse.

1.2 Explicit Parameter Passing (Recommended)

The first service in the route parses the Token, extracts the userId, and passes it explicitly to downstream services, which no longer need to parse the Token. A single API that accepts userId satisfies all three scenarios, preserving atomicity and improving reuse.

Note: The provided API should not be exposed to the external network; internal APIs must be distinguished, e.g., using a path pattern like /api/inside/** , and the gateway should reject external requests to these endpoints.

2. Unified Authorization

2.1 Feign Internal Call

Spring Cloud Gateway + Feign internal calls centralize authentication at the gateway. After verification, the gateway adds user information (e.g., userId) to request headers for downstream services.

Drawback: Service A must define an internal Controller in Service B for Feign to call, increasing code volume.

2.2 Dubbo Internal Call

Spring Cloud Gateway + Dubbo internal calls also centralize authentication at the gateway and forward user information via headers.

Advantages: No extra Controller is needed; only local service and remote DubboService differ, making the code cleaner.

Disadvantages: Slightly increases the technology stack complexity.

2.3 Spring Boot Web + Dubbo (No Gateway)

This design removes the gateway and uses a Spring Boot Web project to perform unified authentication and authorization. The web container should be Undertow (non‑blocking) rather than Tomcat for better throughput.

All service Controllers are integrated into the web application; each service can provide its own Controller module, while the web gateway only contains a startup class that depends on these modules.

Advantages: Simplifies project structure; only service code remains, and performance testing does not need to consider the gateway thread pool.

Disadvantages: Dynamic route configuration via a configuration center is not possible; adding a new service requires redeployment.

3. Non‑Unified Authorization

In this approach, the gateway performs only routing, while each service implements its own authentication, possibly sharing a common auth library.

3.1 Conventional Mode

A generic authentication module is packaged as a jar and integrated into each service. The module provides:

JWT token parsing

Permission interception

Caching (local or Redis)

This mode suits large teams where each microservice is owned by a different group, allowing each service to maintain its own permission rules while sharing the same rule definitions.

3.2 Integration with K8s

When the application gateway is replaced by a K8s Ingress gateway, the Ingress forwards traffic to services via K8s Service load balancing, eliminating the need for a separate service registry.

Example service address: http://goods-svc:8080/api/goods/info/10001 or dubbo://goods-svc:20880.

Feign Example

@FeignClient(name = "user-service", url = "http://goods-svc:8080")
public interface UserServiceClient {
    @GetMapping("/users/{id}")
    User getUserById(@PathVariable("id") Long id);
}

Dubbo Example

@Reference(url = "dubbo://goods-svc:20880")
private DemoService demoService;

The choice between unified and non‑unified authorization depends on project requirements; both approaches are viable.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesDubbofeigngateway
Java High-Performance Architecture
Written by

Java High-Performance Architecture

Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.