背景
私はこの 記事 で提示されている設計を実装したいと思います。
これまでに持っているもの
私はそのほとんどを使用して完了しています:
また、アクセストークンをチェックし、IDPにアクセスしてJWTを作成するZuul PREフィルターを作成しました。次に、JWTがダウンストリームサービスに転送されるリクエストのヘッダーに追加されます。
問題
さて、私の質問は、Zuulとそのフィルターに特化したものです。何らかの理由でAPIゲートウェイで認証が失敗した場合、ルーティングを停止し、フィルターチェーンを継続して呼び出しを転送せずに401で直接応答する方法を教えてください。
現時点では、認証が失敗した場合、フィルターはヘッダーにJWTを追加せず、401はダウンストリームサービスから取得されます。私のゲートウェイがこの不必要な呼び出しを防ぐことを望んでいました。
com.netflix.zuul.context.RequestContext
を使用してこれを行う方法を確認しようとしましたが、ドキュメントが非常に貧弱で、方法が見つかりませんでした。
現在のコンテキストでsetSendZuulResponse(false)
を設定してみてください。これはリクエストをルーティングするべきではありません。コンテキストからremoveRouteHost()
を呼び出すこともできますが、これは同じことを実現します。 setResponseStatusCode
を使用して401ステータスコードを設定できます。
Runメソッド内に次を追加すると、この問題が解決します
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
私は答えるのが非常に遅いことを知っています。あなたは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をリセットします。応答ステータスコードを提供できます。