不允许直接调用微服务。仅允许通过API网关

时间:2016-12-21 12:20:58

标签: java spring rest microservices gateway

也许这是一个奇怪的问题(我是微服务的新手)。但我正在寻找有关如何继续这一点的一些信息。不需要特定于Spring,但这是我目前正在使用的框架。

实施例: 假设我们有两个微服务

a)http://myurlfortesting.com:8085/api/rest/serviceone

b)http://myurlfortesting.com:8090/api/rest/servicetwo

我们已经设置了Spring Zuul(充当API网关),其中包含以下转发来电的规则:

/ rest / one - > http://myurlfortesting.com:8085/api/rest/serviceone

/ rest / two - > http://myurlfortesting.com:8090/api/rest/servicetwo

问题...... 有没有办法阻止用户直接访问A和B中提到的服务(只允许通过API网关提供的服务)?

可以通过设置一些额外的过滤器来使用Springs Zuul(作为API网关),还是在微服务端点中进行设置?

甚至想知道是否有办法甚至不处理微服务端点上不通过API网关的直接调用。

也许这是通过服务器特定规则解决的,与Spring无关?

非常感谢,

/ d

6 个答案:

答案 0 :(得分:4)

假设您有防火墙,您可以将服务器的入站流量限制为Zuul端点所在的端口,并禁止任何人直接访问微服务端口。

如果您想避免使用防火墙路由,可以强制端点在转发请求之前检查特定的HTTP标头或由Zuul设置的内容,但这样做很容易规避。根据我过去的经验,“正确”的方式是通过防火墙来做到这一点。您的应用应负责处理请求。您的防火墙应负责决定谁可以命中特定端点。

答案 1 :(得分:3)

通常,通过实施适当的OAuth服务器来处理这种情况,其中只有您的API网关将处理令牌验证。任何对微服务的直接调用都不会进行正确的令牌交换,因此请求将被中止。

如果您已经在任何云上部署了微服务,那么您可以通过仅将路由暴露给API网关来实现这一点。 是的,防火墙阻止,IP白名单是限制访问微服务的其他一些方法。

答案 2 :(得分:1)

使用反向代理。我们出于相同的目的使用Nginx。对于生产方案,应始终将Api网关部署在负载均衡器之后,以避免网关成为单点故障。此外,网关和服务也部署在VPC中。 enter image description here

答案 3 :(得分:0)

我们正在使用 jHipster-Gateway 达到同样的目的:

查看HERE以获取更详细的架构。

答案 4 :(得分:0)

使用AWS API Gateway执行此操作的正确方法是使用最近推出的' VPC Link'集成,用于保护API网关与VPC内后端之间的连接。

https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-endpoint-integrations-with-private-vpcs/

答案 5 :(得分:0)

嘿,我终于找到了一种使用微服务架构仅接受来自API网关的请求的解决方案,为此,您可以创建一个过滤器,并像Zuul一样充当代理,检查标头“ X-Forwarded-Host”(如果它与网关服务不匹配,然后返回未经授权的异常。

public class CustomGatewayFilter extends GenericFilterBean {

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
        throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    String proxyForwardedHostHeader = request.getHeader("X-Forwarded-Host");

    if (proxyForwardedHostHeader == null || !proxyForwardedHostHeader.equals(GatewayConstant.getGatewayURL())) {
        UnauthorisedException unauthorisedException = new UnauthorisedException("Unauthorized Access",
                "Unauthorized Access, you should pass through the API gateway");
        byte[] responseToSend = restResponseBytes(unauthorisedException.getErrorResponse());
        ((HttpServletResponse) response).setHeader("Content-Type", "application/json");
        ((HttpServletResponse) response).setStatus(401);
        response.getOutputStream().write(responseToSend);
        return;
    }
    chain.doFilter(request, response);
}

private byte[] restResponseBytes(ErrorResponse errorResponse) throws IOException {
    String serialized = new ObjectMapper().writeValueAsString(errorResponse);
    return serialized.getBytes();
}

}

不要忘记在SpringSecurity Configuration中添加自定义过滤器

.and().addFilterBefore(new CustomGatewayFilter(), ConcurrentSessionFilter.class);