背景
我想实现此article中提供的设计。
到目前为止我有什么
我完成了大部分工作:
我还编写了一个Zuul PRE过滤器,用于检查访问令牌,联系IDP并创建JWT。然后将JWT添加到转发到下游服务的请求的标头中。
问题
现在我的问题非常具体针对Zuul及其过滤器。如果由于任何原因在API网关中验证失败,我怎样才能停止路由并直接用401响应而不继续过滤链并转发呼叫?
如果验证失败,过滤器不会将JWT添加到标头中,401将来自下游服务。我希望我的网关可以阻止这种不必要的呼叫。
我试图了解如何使用com.netflix.zuul.context.RequestContext
来执行此操作,但文档很差,我找不到方法。
答案 0 :(得分:9)
您可以尝试在当前上下文中设置setSendZuulResponse(false)
。这不应该路由请求。您也可以从上下文中调用removeRouteHost()
,这将实现相同的目标。您可以使用setResponseStatusCode
设置401状态代码。
答案 1 :(得分:4)
在run方法中添加以下内容,它将解决此问题
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
答案 2 :(得分:0)
我知道我很晚才回答 您可以使用zuul的预过滤器进行操作。您必须遵循的步骤如下所示。
//1. create filter with type pre
//2. Set the order of filter to greater than 5 because we need to run our filter after preDecoration filter of zuul.
@Component
public class CustomPreZuulFilter extends ZuulFilter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public Object run() {
final RequestContext requestContext = RequestContext.getCurrentContext();
logger.info("in zuul filter " + requestContext.getRequest().getRequestURI());
byte[] encoded;
try {
encoded = Base64.encode("fooClientIdPassword:secret".getBytes("UTF-8"));
requestContext.addZuulRequestHeader("Authorization", "Basic " + new String(encoded));
final HttpServletRequest req = requestContext.getRequest();
if (requestContext.getRequest().getHeader("Authorization") == null
&& !req.getContextPath().contains("login")) {
requestContext.unset();
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
} else {
//next logic
}
}
} catch (final UnsupportedEncodingException e) {
logger.error("Error occured in pre filter", e);
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 6;
}
@Override
public String filterType() {
return "pre";
}
}
requestContext.unset()将重置当前线程活动请求的RequestContext。并且您可以提供响应状态代码。