I.はじめに
では最後の記事ルーティング(ルータ):、我々は最も基本的な機能を持つゲートウェイとして春クラウドZuulについて学びました。フィルター(フィルター):この記事では、春の雲Zuul者の他のコア機能に焦点を当てます。
フィルター効果
アプリケーションが提供する当社のマイクロサービスのインタフェースが統一APIゲートウェイエントリを介し得ることへのクライアントアクセスであるように、我々は、ルーティングの要求を達成することができました。
しかし、多くの場合、一定の制限へのアクセスを必要とするユーザー・インターフェース・マイクロ回路アプリケーションによって要求された各クライアントサービスは、システムはマイクロサービス・インターフェースのすべてが彼らに開放されてなりません。しかし、現在のサービスのルーティング機能は、すべての要求は、特定のアプリケーションと戻り結果に転送されます、予約なしで、そのような権利を制限するものではありません。
セキュリティチェックを実現し、クライアントから要求されたアクセス権を制御するために、最もシンプルかつ残忍な方法は、署名を検証し、アクセス権のセットを識別するために、各サービスアプリケーションの実装ミクロフィルターや迎撃のためです。しかし、このアプローチは望ましいことではない、それは多くの場合、検証ロジックの同じ様々な環境下でシステムは、実質的に同一または類似しているとして、このような実装は、同様のチェックになるだろう、将来的にシステムを維持することの難しさを増加しますロジック・コードはマイクロに様々なサービスに配信され、冗長なコードは、我々は見たくないということです表示されます。そのため、良い方法は、別々の認証サービスを構築するためにチェックロジックをスピンオフすることです。分離が完了した後、多くの開発者は、認証サービスを呼び出すことにより、パリティを達成するためのマイクロサービスアプリケーションに直接だろうが、そのようなアプローチは、単に認証ロジックの分離を解決することであり、この部分は、本質的に、ではありません、アマチュアは、元の論理マイクロサービスアプリケーション、冗長ブロッカーまたはフィルターがまだ存在して分割しません。
このような問題のために、より良いアプローチは、ゲートウェイサービスの前面からこれらの非動作の性質の完了を確認することです。ゲートウェイサービスのほか以来、外部クライアントは、我々のシステム統一の入り口へのアクセス権を持って、チェックは、特定のビジネスとは何の関係もないので、なぜ発生し、次いで濾過し、前方のチェックやフィルタ着信要求の時点で完全ではなくありませんより長い遅延を要求します。一方、チェックサムを実行することにより、精密サービスゲートウェイアプリケーション側が複雑なフィルタとインターセプターの多様で除去することができるマイクロサービスアプリケーションのインタフェースの開発とテストの複雑さもそれに応じて減少していることができるいます。
:クライアント上のチェックは、APIゲートウェイを要求達成するために、我々は別の春クラウドZuulのコア機能を使用する必要がありますフィルタを。
Zuulは、開発者は、APIゲートウェイインターセプトに要求を実現することを可能にし、定義されたフィルタを介して濾過し、この方法は、達成するのが非常に簡単です。
二、フィルターのライフサイクル
フィルタのライフサイクルは、4つ、すなわち、「PRE」、「ルーティング」、「POST」と「ERROR」を有し、全体のライフサイクルは、以下の図で表すことができます。
Zuulの機能のほとんどはフィルタによって実装され、要求の典型的なライフサイクルに対応するフィルタのこれらのタイプ。
- PRE:リクエストがルーティングされる前に、このフィルタが呼び出されます。私たちは、認証のためにこのフィルタを使用してデバッグ情報をクラスタマイクロサービスレコード内の要求を選択することができます。
- ルーティング:このフィルタは、ルーティングマイクロサービスへの要求を。このフィルタはマイクロに送信されたサービス要求を構築するために使用され、またはApacheのHttpClient Netfilxリボンマイクロサービス要求を使用しています。
- POST:サービスはマイクロにルーティングされた後、このフィルタは実行されます。そのようなフィルタ応答は、統計や指標を収集し、標準的なHTTPヘッダーを追加するために使用することができる、応答がクライアントにマイクロサービスから送信されます。
- ERROR:フィルタ他のステージエラーの実装。デフォルトのフィルタタイプに加えて、Zuulはまた、私たちは、カスタムフィルタの種類を作成することができます。例えば、我々はリア転送マイクロサービスに要求することなく、直接応答Zuulで生成、フィルタの静的タイプをカスタマイズしていることができます。
三、デフォルトのフィルターのZuul実現
タイプ | オーダー | フィルタ | 機能 |
---|---|---|---|
前 | -3 | ServletDetectionFilter | マーキングプロセスサーブレットタイプ |
前 | -2 | Servlet30WrapperFilter | HttpServletRequestのリクエストをパッキング |
前 | -1 | FormBodyWrapperFilter | パッキングリクエストボディ |
ルート | 1 | DebugFilter | マーク・デバッグフラグ |
ルート | 5 | PreDecorationFilter | その後の使用のための処理要求コンテキスト |
ルート | 10 | RibbonRoutingFilter | サービスIDの要求の転送 |
ルート | 100 | SimpleHostRoutingFilter | URL要求の転送 |
ルート | 500 | SendForwardFilter | 前方への要求を転送 |
役職 | 0 | 送信エラーフィルタ | エラー処理要求の応答 |
役職 | 1000年 | SendResponseFilter | 通常の処理要求応答 |
第四に、無効に指定されたフィルタ
あなたはフィルタを無効にするapplication.yml必要性、フォーマットを設定することができます zuul.<SimpleClassName>.<filterType>.disable=true
。
たとえば、無効に org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter
設定しています
zuul:
SendResponseFilter:
post:
disable: true
第五に、カスタムフィルタ
サービスは外部のすべての要求に対処するためのゲートウェイであるので、我々はそのような要求として、回避セキュリティリスクへ順に、我々は一定の制限を要求するために行う必要があり、そのような場面があることを前提とすると、トークン要求は、要求がなければ、下がるしていきましょう含まれていトークン直接リターンと弾力のヒント。
ブログ記事のプロジェクト、最初のカスタムフィルタ、ZuulFilter抽象クラスの継承、以下のようなパラメータは、トークンに含まれているかどうかを確認するためにrun()メソッドの場合:
package com.example.apigateway.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import javax.servlet.http.HttpServletRequest;
/**
* @ClassName TokenFilter
* @Description TODO
* @Author lhw
* @Date 2020/3/21 13:59
* @Version 1.0
**/
public class TokenFilter extends ZuulFilter {
/**
* 过滤器的类型,它决定过滤器在请求的哪个生命周期中执行。
* 这里定义为pre,代表会在请求被路由之前执行。
* @return java.lang.String
**/
@Override
public String filterType() {
return "pre";
}
/**
* filter执行顺序,通过数字指定
* 数字越大,优先级越低
* @return int
**/
@Override
public int filterOrder() {
return 0;
}
/**
* 判断该过滤器是否需要被执行。这里我们直接返回了true,因此该过滤器对所有请求都会生效。
* 实际运用中我们可以利用函数来指定过滤器的有效范围。
* @return boolean
**/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的具体逻辑
* @return java.lang.Object
**/
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
if(token==null || token.isEmpty()){
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("token is empty");
}
return null;
}
}
上記のコードで実装フィルタは、我々が継承する ZuulFilter
抽象クラスをし、カスタムフィルタを実装するために、次の4つのメソッドをオーバーライドします。これら4つのメソッドが定義されました。
filterType()
:要求の中にライフサイクルの決定の実施をフィルタリングするフィルタの種類、。ここで定義されたpre
要求がルーティングされる前代表が実行されます。filterOrder()
:実行次フィルタ。多段フィルタに要求があった場合、順次メソッドによって返される値に応じて実行される必要があります。デジタルは、より多くの、低い優先順位を指定します。shouldFilter()
:フィルタを実行する必要があるかどうかを決定します。ここでは、直接返すtrue
ので、フィルタはすべてのリクエストで有効になります。実用的なアプリケーションでは、我々は有効な範囲フィルタを指定するには、この機能を使用することができます。run()
:指定された論理フィルタ。ここでは、パスctx.setSendZuulResponse(false)
要求は、ルーティングされ、その後、されていない作るZuulをフィルタリングctx.setResponseStatusCode(401)
が返す誤ったコードを設定し、もちろん、我々はさらに、例えば、返品を最適化することができctx.setResponseBody(body)
、戻り本文の内容を編集します。
カスタムフィルタの実現において、それが直接反映されません、我々はまた、例えば、以下の主要なカテゴリのアプリケーションの増加をフィルタを開始するには、特定のBeanを作成する必要があります。
package com.example.apigateway;
import com.example.apigateway.filter.TokenFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
@EnableZuulProxy
@SpringBootApplication
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
@Bean
public TokenFilter tokenFilter(){
return new TokenFilter();
}
}
うち api-gateway
サービスは上記の変換を完了した後、我々はそれを再起動して、以下の要求、検証を行うために上記で定義されたフィルタを開始することができます。
- ログイン のhttp:// localhostを:14000 /消費者 /ハロー/ windmtは 401エラーを返し、
token is empty
- 訪問 のhttp:// localhostを:14000 /消費者 ?/ハロー/ windmtトークン=トークン を適切にルーティングされた インターフェイスとリターン
consumer
/hello
Hello, windmt
制限機能を要求し、署名検証、検証機関:我々は、フィルタリング、そのようなものとして、ブロッキング一般的な要求のいくつかの非ビジネス・ロジックの実装のサービスゲートウェイに自分のニーズに応じて定義することができます。