简体   繁体   English

在 Spring Boot AWS 容器中重写 url

[英]Rewrite url in Spring Boot AWS container

I have a spring boot app that is likely to be Software as a Medical Device, and has a section that is protected with oauth2, and a demo section.我有一个 Spring Boot 应用程序,它可能是作为医疗设备的软件,并且有一个受 oauth2 保护的部分和一个演示部分。 I'd like to have these at separate hostnames, eg protected.example.com and demo.example.com.我想将它们放在单独的主机名中,例如protected.example.com 和demo.example.com。 I can do this perfectly well with a simple Apache2 proxypass directive:我可以用一个简单的 Apache2 proxypass 指令完美地做到这一点:

ServerName demo.example.com
ProxyPassReverse / http://localhost:9000/demo/
ProxyPass / http://localhost:9000/demo/

The problem is that I need to deploy this on Amazon Web Services, which won't let me redirect to a path, only to a server.问题是我需要在 Amazon Web Services 上部署它,它不会让我重定向到路径,只能重定向到服务器。 I've implemented tuckey-urlrewrite-filter, but it gets invoked AFTER SecurityContextPersistenceFilter, and putting it before that filter fails:我已经实现了 tukey-urlrewrite-filter,但它在 SecurityContextPersistenceFilter 之后被调用,并将它放在该过滤器失败之前:

17:40:00 ERROR o.a.c.c.C.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.lang.NullPointerException: null
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:373)

I'm not sure I want to bypass Spring Security for any url in https://demo.example.com .我不确定是否要为https://demo.example.com中的任何 url 绕过 Spring Security。 I understand that I could break out demo into a separate container/context/whatever, but this seems computationally redundant and risks having parallel codebases.我知道我可以将演示分解成一个单独的容器/上下文/任何东西,但这似乎在计算上是多余的,并且存在并行代码库的风险。 My goal is for someone who is invited to view demo.example.com to not know that protected.example.com exists.我的目标是让受邀查看 demo.example.com 的人不知道 protected.example.com 存在。 Is there a "simple" approach to this:是否有一个“简单”的方法来解决这个问题:

  1. A simple way to allow demo.example.com to AllowAll()一种允许 demo.example.com 允许 All() 的简单方法
  2. A way to put /demo on a separate port一种将 /demo 放在单独端口上的方法
  3. A way to allow urlrewrite-filter to go to the top of the filter chain.一种允许 urlrewrite-filter 进入过滤器链顶部的方法。
  4. An undocumented feature in AWS AWS 中未记录的功能

Unleash your creativity!释放你的创造力!

Here is what I've learned.这是我学到的。 The problem was putting the Tuckey (or ANY filter) before SecurityContextPersistenceFilter.问题是将 Tuckey(或任何过滤器)放在 SecurityContextPersistenceFilter 之前。 The request doesn't have PathInfo populated until after the HeaderWriterFilter.直到 HeaderWriterFilter 之后,请求才填充 PathInfo。 It does have the URI.它确实有 URI。 Moving the filter later in the chain solves this problem, but it should precede authentication filters.在链中稍后移动过滤器可以解决这个问题,但它应该在身份验证过滤器之前。

What I didn't mention in my original post was that /demo and the protected area share the static resources, so prepending /demo on URIs for demo.example.com must be avoided for these.我在原始帖子中没有提到的是 /demo 和保护区共享静态资源,因此必须避免在 demo.example.com 的 URI 上添加 /demo。 The solution is:解决方案是:

public class rewriteDemoFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String hostname = request.getServerName();
        String path = request.getRequestURI();
        String base;
        if (path.length() == 1) {
            base = "";
        } else {
            String[] components = path.split("/");
            base = components[1];
        }
        if (hostname.equalsIgnoreCase("demo.example.com")) {
            switch (base) {
                case "js":
                case "sounds":
                case "webjars":
                case "css":
                case "images":
                    break;
                default:
                    path = "/demo" + path;
            }
            request.getRequestDispatcher(path).forward(servletRequest, servletResponse);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
     }
}

This filter should be added in the Security configuration:此过滤器应添加到安全配置中:

.addFilterAfter(new rewriteDemoFilter(), HeaderWriterFilter.class)

The advantage of this solution is that URL mangling is all done in the Spring app, so my development environment (Apache forwarding to the Spring app launched from the command line) and my AWS environment (a Docker image running in an ECS task) don't require distinct mechanisms to rewrite the path.此解决方案的优点是 URL 修改全部在 Spring 应用程序中完成,因此我的开发环境(Apache 转发到从命令行启动的 Spring 应用程序)和我的 AWS 环境(在 ECS 任务中运行的 Docker 映像)不要' t 需要不同的机制来重写路径。 The downside is that my security is bypassed, but since the filter only processes requests destined for the unprotected realms of the site and the strict firewall removes dangerous patterns from the URI, I'm moderately optimistic that only small trucks can drive through the hole.不利的一面是我的安全被绕过了,但是由于过滤器只处理发往站点未受保护领域的请求,并且严格的防火墙从 URI 中删除了危险模式,所以我对只有小型卡车可以通过这个洞持适度乐观的态度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS cloudfront url重写 - AWS cloudfront url rewrite 在 aws 上忽略基于 url 到 spring boot 2 应用程序的黑客尝试是否安全? - Is it safe to ignore hacking attempts based on url to spring boot 2 application on aws? 如何从 AWS AppConfig 设置 Spring 引导数据源 URL? - How to set up Spring Boot datasource URL from AWS AppConfig? Spring Boot AWS ElastiCache - Spring Boot AWS ElastiCache AWS Kendra 和 Spring 启动 - Aws Kendra and Spring boot AWS Lambda (URL) 重写流程 - AWS Lambda (URL) rewrite flow 连接到 AWS ECS 上不同 docker 容器中的 spring-boot 应用程序的错误请求 - Bad Request Connecting to a spring-boot app in a different docker container on AWS ECS 如何使用Tomcat托管的Spring Boot应用程序从Docker Container通过JDBC访问Oracle AWS RDS - How to access Oracle AWS RDS through JDBC from Docker Container with Spring boot application hosted on Tomcat 如何在 spring 引导容器中获取 lambda 授权方添加的自定义上下文信息? AWS Apigateway HTTP API - How to get custom context information added by lambda authorizer in spring boot container? AWS Apigateway HTTP API 如何在 AWS 上托管的 docker 容器内使用 spring 引导加载 static 文件? - How to load static files with spring boot inside a docker container hosted on AWS?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM