从zuul过滤器发送重定向

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (262)

我正在实现我们的zuul过滤器集的添加。此附加过滤器将查看标头并确定应将请求重定向到我将配置的已知位置。

这是过滤器的run方法的主体

 @Override
    public Object run() {
        log.debug("Running the PreRouteTransMarkAndLoggingZuulFilter filter ");
        // retrieve redirect URL
        String redirectURL = filterConfigurationBean.getRedirectURL();
        if (redirectURL.isEmpty()) {
            return null;
        }
        // get the white list for allowed entries
        Set<String> whiteList = new HashSet<>(Arrays.asList(filterConfigurationBean.getWhiteList().split(",")));
        RequestContext ctx = RequestContext.getCurrentContext();
        // if request url is part of white list then allow
        String url = ctx.getRequest().getRequestURL().toString();
        if (checkWhiteList(url, whiteList)) {
            return null;
        }
        // get headers
        // check if an authorization header is present
        if (validHeader(ctx.getRequest())) {
            return null;
        }
        // if it got to here then if no header then redirect request
        try {
            ctx.getResponse().sendRedirect(redirectURL);
        } catch (IOException e) {
            log.error("unable to send a redirect to the login page");
        }
        return null;
    }

好的,所以我实现并测试了它(它被定义为预过滤器,因为我不希望在路由阶段发送请求。

在某个地方,更进一步,它抛出异常。

2017-06-26 17:00:36.482  WARN 6267 --- [tp1303192419-23] o.s.c.n.z.filters.post.SendErrorFilter   : Error during filtering
com.netflix.zuul.exception.ZuulException: Filter threw Exception
    at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:227)
    at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157)
    at com.netflix.zuul.FilterProcessor.postRoute(FilterProcessor.java:92)
    at com.netflix.zuul.ZuulRunner.postRoute(ZuulRunner.java:87)
    at com.netflix.zuul.http.ZuulServlet.postRoute(ZuulServlet.java:107)
    at com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:88)
    at org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:157)
    at org.springframework.cloud.netflix.zuul.web.ZuulController.handleRequest(ZuulController.java:44)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:206)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:208)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at com.cisco.phisphere.routerservice.BasicCORSFilter.doFilter(BasicCORSFilter.java:78)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:564)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:317)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
    at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128)
    at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:126)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.UndeclaredThrowableException: null
    at org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:317)
    at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.run(SendResponseFilter.java:115)
    at com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:112)
    at com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193)
    ... 75 common frames omitted
Caused by: org.eclipse.jetty.io.EofException: Closed
    at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:476)
    at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.writeResponse(SendResponseFilter.java:214)
    at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.writeResponse(SendResponseFilter.java:183)
    at org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter.run(SendResponseFilter.java:112)
    ... 77 common frames omitted

所以我的问题是这个。这是从zuul执行重定向的正确方法吗?

我有一个明确定义的重定向条件和一个定义良好的位置来发送它。如果条件被保留但是被重定向到外部位置,我不希望此请求继续。

谢谢

提问于
用户回答回答于

好的,所以我玩了一遍并想出来了。

您需要通过设置ctx.setSendZuulResponse(false)来确保不触发RibbonRoutingFilter,因为该过滤器使用它来确定是否应该触发。

接下来设置ctx.put(FORWARD_TO_KEY,redirectURL)以确保将触发SendForward过滤器。将redirectURL设置为您想要的位置。

还要设置ctx.getResponse()。sendRedirect(redirectURL),否则它将作为前缀添加到原始服务的路由路径,重定向将失败。

@Override
public Object run() {
    log.debug("Running the AuthorizationPassFilter filter ");

    // retrieve redirect URL
    String redirectURL = filterConfigurationBean.getRedirectURL();

    if (redirectURL.isEmpty()) {
        return null;
    }

    // get the white list for allowed entries
    Set<String> whiteList = new HashSet<>(Arrays.asList(filterConfigurationBean.getWhiteList().split(",")));

    RequestContext ctx = RequestContext.getCurrentContext();

    // if request url is part of white list then allow
    String url = ctx.getRequest().getRequestURL().toString();
    if (checkWhiteList(url, whiteList)) {
        return null;
    }

    // get headers
    // check if an authorization header is present
    if (validHeader(ctx.getRequest())) {
        return null;
    }

    // if it got to here then if no header then redirect request
    try {
        ctx.setSendZuulResponse(false);
        ctx.put(FORWARD_TO_KEY, redirectURL);
        ctx.setResponseStatusCode(HttpStatus.SC_TEMPORARY_REDIRECT);
        ctx.getResponse().sendRedirect(redirectURL);
    } catch (IOException e) {
        log.error("unable to send a redirect to the login page");
    }

    return null;

}

热门问答

关于web表情包集成?

最爱开车啦互联网的敏感者
推荐
表情使用方式有两种方式: 1)是使用 TIMFaceElem 中的 index,标识表情的索引,比如 Android 和 iOS 两端都有同一套表情图,索引2为笑脸,index=2 就表示笑脸,两端发送和接收都显示同一张索引表情图片即可。 2 ) 是使用 TIMFaceElem ...... 展开详请

如何将本地的.json格式的文件部署到服务器上, 通过url请求?

使用 CDS-Mask 做数据合作,怎么确保双方都不能反推对方的 ID?

用户2134289

腾讯科技 · 高级工程师 (已认证)

推荐
您好,两种方案可以解决您的需求 1)如果您这边ID不需要在业务上使用,将ID进行加星脱敏即可,加星后的所有数据字符将变为*,无法还原; 2)如果您这边ID在业务上需要使用,也就是ID在处理后必须保持唯一性,那么需要采用腾讯数港算法解决该问题,数港算法目前灰度中,如需要申请,烦请通...... 展开详请

如何调整版本库大小?

marssun_1984

腾讯 · 高级产品经理 (已认证)

腾讯研发管理部产品经理
推荐

cos.sliceUploadFile支持断点续传吗?

如果用的是 cos-js-sdk,那么 cos.restartTask 是会断点续传的,用法没有问题。 PS: sdk 使用可以参考 demo.js https://github.com/tencentyun/cos-js-sdk-v5/blob/master/demo/demo...... 展开详请

MySQL还要另外购买吗?

蒋小爱

腾讯云 · 技术支持 (已认证)

推荐已采纳
您好,您可在服务器中自建MySQL ,同时腾讯云提供数据库 MySQL(TencentDB for MySQL)让用户可以轻松在云端部署、使用 MySQL 数据库。MySQL 是世界上最流行的开源关系数据库,通过云数据库 MySQL,您在几分钟内即可部署可扩展的 MySQL ...... 展开详请

所属标签

扫码关注云+社区

领取腾讯云代金券