繁体   English   中英

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

[英]Spring security change redirect URL to use HTTPS instead of HTTP

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

部署在云上的微服务可通过HTTPS URL访问。 由于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)

以下是我的尝试

的x转发-原

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

需要渠道HTTPS

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

拦截器/过滤器

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

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

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

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

@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);

    }
}

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

任何提示都表示赞赏。

如果要更新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 / HttpResponseInterceptor

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

SpringFramework提供了HandlerInterceptor。 这将拦截所有http请求,但可用于不断检查身份验证和授权。 您必须提供3种方法的实现(如果您不使用它们,只需实现一个空方法)。 然后,您可以将代码放在preHandle方法中。

public class AuthenticationInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM