【问题标题】:Should internal micro-services communication goes through zuul gateway?内部微服务通信是否应该通过zuul网关?
【发布时间】:2020-10-23 13:37:35
【问题描述】:

我正在使用 Spring 框架创建一个微服务项目,但是我在内部微服务调用方面遇到了问题。 当用户调用微服务A的一个端点时,请求通过zuul网关检查jwt令牌是否有效,以及用户的角色是否允许他访问这个端点。 如果一切正常,用户将被重定向到 微服务 A 的端点。 到目前为止,一切都清楚了。但是当 微服务 A 的端点调用 微服务 B 的另一个端点时,问题就开始了。 通常,我要做的是将用户的 jwt 在请求的标头中传递给 微服务 B.. 但是如果用户的角色不允许他访问 的端点怎么办>微服务 B? 我现在正在做的是在 microservice A 中生成一个具有 SYSTEM 角色的新 jwt,以便在调用 microservice B 时使用它。 但我认为这不是一个好习惯,因为这个原因: 生成一个新的 jwt 迫使我将我的私钥放在每个微服务中,以便每次我需要它时它都可以创建一个有效的 jwt。我知道我只能让一个微服务这样做,并让其他微服务调用它来询问new jwt.. 但我可能会陷入更严重的安全漏洞,例如,如果用户查看其互联网流量,他将能够看到角色为 SYSTEM 的 jwt 并使用它来做他想做的事想要。

这一切只是因为微服务A通过zuul网关调用微服务B

我的问题是:如果呼叫是内部的,是否必须通过 zuul? 微服务A可以不经过zuul调用微服务B吗?这种情况下jwt的验证只有在用户调用微服务A的时候才进行,一旦被zuul验证,微服务就可以内部通信,而无需在每次内部调用中验证jwt?它还允许我避免为每个内部调用创建具有 SYSTEM 角色的 jwt。

这是一个好习惯吗?这不会导致安全问题吗?这不会导致任何其他问题,例如在部署期间吗?还有其他更好的解决方案吗?

【问题讨论】:

  • 微服务 A 和 B 是否受 Spring Security 保护?
  • @MuriloGóesdeAlmeida 不,spring security 仅在 zuul 网关中实现。我认为验证应该只在 zuul 中进行,不是吗?
  • 视情况而定,我有一个项目在微服务 A、B 和网关中使用 Spring Security,因为我想强力保护所有微服务。但是,如果微服务受到例如防火墙的保护,那就没问题了。如果在微服务 B 中不使用 Spring Security,如何控制角色?
  • 那么可以不通过zuul就让微服务内部通信吗?

标签: java spring-boot spring-security microservices


【解决方案1】:

是的,您可以使用微服务 A 调用微服务 B,而无需通过 Zull。可能您正在使用 Eureka 服务器/客户端,然后您可以使用 @LoadBalanced 注释来利用它。假设您将使用 RestTemplate:

在配置类中创建一个 Bean:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    return restTemplate;
}

那么当你想使用微服务A调用微服务B时,​​你只需在http请求中输入名称即可(假设微服务的application.name为“microserviceb”:

@Autowired
RestTemplate restTemplate;
        
    public Object getObject(String xyz) {
    Object result = restTemplate.getForObject("http://microserviceb/someresource/{xyz}", Object.class, xyz);        
    return result;
}

如果你想在这个申请中继续传递令牌,你可以在RestController方法中得到他,像这样:

@GetMapping("/someMapping")
public String someMethod(@RequestHeader("Authorization") String accessToken) {
            
   HttpHeaders headers = new HttpHeaders();
   headers.setContentType(MediaType.APPLICATION_JSON);
   headers.set("Authorization", "Bearer "+accessToken);
            
   HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
   String result = restTemplate.postForObject(http://microserviceb/someresource, entity, String.class);
   return result;           
}

我在微服务通信方面没有任何问题,唯一应该避免的是客户端直接调用一些微服务而不传入网关(这种情况下你可以使用一些防火墙配置或spring security)

【讨论】:

    猜你喜欢
    • 2019-05-01
    • 2018-06-30
    • 2021-02-01
    • 2022-01-01
    • 2019-10-01
    • 2018-04-17
    • 2018-05-07
    • 2019-10-16
    相关资源
    最近更新 更多