微服务JWT认证求助:获取Token后调用用户服务GET接口报错
Got it, let's work through this issue step by step—this is a common pain point when dealing with service-to-service JWT propagation in Spring Cloud/Eureka setups. Here's how to resolve it:
1. First, clarify how you're calling the service
You mentioned hitting http://localhost:8072/users/logon directly:
- If this is a direct call (bypassing Eureka), double-check your Postman request:
- Ensure you've added the
Authorizationheader with the formatBearer <your-jwt-token>(no typos like "Authroization" or missing the "Bearer " prefix). - Verify the token isn't expired or malformed by decoding it with a tool like jwt.io.
- Ensure you've added the
If you're calling via Eureka service discovery (using the service name instead of localhost), the problem is almost certainly missing request header propagation—Eureka/RestTemplate/Feign don't forward headers like Authorization by default.
2. Configure request header propagation for service-to-service calls
For RestTemplate users
Add an interceptor to copy the incoming Authorization header to outgoing requests:
@Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.getInterceptors().add((request, body, execution) -> { // Grab the current request's auth header HttpServletRequest currentRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String authHeader = currentRequest.getHeader("Authorization"); if (authHeader != null) { request.getHeaders().add("Authorization", authHeader); } return execution.execute(request, body); }); return restTemplate; }
For FeignClient users
Enable header forwarding with a custom request interceptor:
- First, make sure you have the OpenFeign dependency (if using Spring Cloud):
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
- Create a Feign configuration class:
@Configuration public class FeignAuthConfig { @Bean public RequestInterceptor authHeaderInterceptor() { return requestTemplate -> { HttpServletRequest currentRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String authHeader = currentRequest.getHeader("Authorization"); if (authHeader != null) { requestTemplate.header("Authorization", authHeader); } }; } }
- Attach this config to your FeignClient interface:
@FeignClient(name = "user-service", configuration = FeignAuthConfig.class) public interface UserServiceClient { @GetMapping("/users/logon") ResponseEntity<User> getLogonDetails(); }
3. Fix ThreadLocal context loss (if using async/Hystrix)
If your service uses async methods or Hystrix for circuit breaking, the RequestContextHolder (which holds the request headers) can lose its context across threads:
- For Hystrix, set the isolation strategy to
REQUESTin yourapplication.properties:
hystrix.command.default.execution.isolation.strategy=REQUEST
- For async code, manually pass the context:
// Capture the context before starting the async task ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); CompletableFuture.runAsync(() -> { // Set the context in the async thread RequestContextHolder.setRequestAttributes(attributes); // Call your downstream service here });
4. Verify the user service's JWT filter
Double-check that your user service's JWT validation logic is correctly reading the header:
public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String authHeader = request.getHeader("Authorization"); if (authHeader == null || !authHeader.startsWith("Bearer ")) { throw new RuntimeException("Authorization token is missing"); } String token = authHeader.substring(7); // Your token validation logic here filterChain.doFilter(request, response); } }
Ensure this filter is registered to intercept the /users/logon endpoint.
内容的提问来源于stack exchange,提问作者Kunle Ajiboye

