Spring 安全更改重定向 URL 以使用 HTTPS 而不是 HTTP

11t*_*ion 7 java spring spring-security

我正在使用受 Spring Security SSO 登录(使用 Cloudfoundry UAA)保护的 Spring 微服务。

部署在云上的微服务可通过HTTPSURL访问。由于 HTTPS URL 属于 ELB(负载均衡器/Web 服务器),因此来自 ELB 对微服务的实际请求会发生HTTP。因此,Spring 在将用户重定向到登录页面时会在302 Location标头中生成 HTTP URL 而不是 HTTPS URL 。

以下是流程

Browser
    ->(https://mymicroservice.com) Unauthenticated request (Load balancer)
        ->(http://internal_lan_ip:someport) Microservice
            -> 302 Location http://mymicroservice.com/login
                -> Browser http://mymicroservice.com/login (failed)

In short it goes from HTTPS -> HTTP -> 302 HTTP (failed as ELB doesn't serve on HTTP)
Run Code Online (Sandbox Code Playgroud)

以下是我尝试过的

x-forwarded-proto

由于负载平衡器也没有x-forwarded-proto正确填充到HTTPS,而是给了我HTTP,我不能使用 Spring 对它的支持。

需要通道 HTTPS

它也不起作用,因为它会导致来自 Spring 的无限重定向,因为 Spring 从未收到来自 的 HTTPS 请求ELB,尽管正确生成了 HTTPS 重定向 URL。

拦截器/过滤器

使用 aServletFilter检查响应头Location,如果存在则替换http://https://.

坦率地说,最后一个选项是我的最后一个选项,因为我不控制 ELB 配置。

现在的问题是,在 spring 重定向到/loginURL后,我无法拦截响应,而URL 又应该重定向到 SSO URL。

我尝试了拦截器的各种组合(postHandle、afterCompletion),使用 Spring security 将其注入到过滤器链中的不同位置,最后将过滤器顺序设置为最低。这些都不会在重定向后拦截未经身份验证的请求。

@Component
@Order(Ordered.LOWEST_PRECEDENCE)
class RedirectUrlProtocolUpdaterFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String locationHeader = response.getHeader("Location");
        System.out.println("############ inside interceptor");

        for(String name: response.getHeaderNames()) {
            System.out.println(name + " : " + response.getHeader(name));
        }

        if(locationHeader != null && locationHeader.startsWith("http://")) {
            System.out.println("###################### setting location header");

            locationHeader = locationHeader.replaceAll("http://", "https://");
            response.setHeader("Location", locationHeader);
        }

        filterChain.doFilter(request, response);

    }
}
Run Code Online (Sandbox Code Playgroud)

如何/login在过滤器/拦截器中正确拦截Spring Security的重定向并更新 Location 标头以包含正确的协议?

任何提示表示赞赏。

小智 0

如果您想更新 Location 标头信息,您可以尝试使用 HttpResponseInterceptor。

这是来自 google HttpResponseInterceptor 的使用示例: https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/ http/HttpResponse拦截器

其他选项来自 Apache: https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/class-use/HttpResponseInterceptor.html