I.はじめに
私の意見では、マイクロサービスではゲートウェイが実際に最も重要なものです。サービスごとに経路分散や負荷分散を行うだけではありません。彼はマイクロサービス全体のセキュリティも保証できます。例: xxs 攻撃、SQL インジェクション。また、Request リクエスト、クロスドメイン、グローバル例外処理などで検証が必要なデータもあり、これらはすべてゲートウェイに書き込む必要があります。
ゲートウェイは、マイクロサービスに高い同時実行性と高可用性を提供するだけではありません。そして高いセキュリティ。今回はGatewayの簡単な使い方を整理してみます。(あまりにも複雑な場合は来られません)。
xxs 攻撃: ハッカーの目的を達成するために、リクエストに HTML 言語または JavaScript を挿入することにより、Web サイトのページを変更することです。
Web ページは HTML タグ言語によって完成され、習得が簡単であることは誰もが知っています。Web アプリケーションに xxs インターセプトがないことを想像してみましょう。次に、ランダムな人が名前を登録するときに名前の横に A タグを付けます。好き:
<a href="xxxx.com"> ダニエル ウー</a>
そしてこの時点で、私たちのウェブサイトはpの合計を集める場所になります。彼らは宣伝をしますが、私たちはミシンを踏みます。なんと恐ろしいことでしょう。
これがxxsについての私の理解です。それが何なのか正確には分かりません。
------------------------------------------
SQL インジェクション: 上記の xxs に似ていますが、SQL インジェクションは区別するのがより困難です。select は英語ユーザーのユーザー名として使用されるため、リクエストの入力パラメーターに表示されるのが通常です。1本のスティックですべてのリクエストを殺すことはできません。したがって、このとき、ユーザーのリクエストに含まれるパラメータが犯罪に該当するかどうか、いや、実行可能な SQL ステートメントを構成しているかどうかを正規表現を使用して判断する必要があります。
2. 環境構築
1.Maven の依存関係
<!-- Nacos服务注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- gateway依赖 没有版本,因为在父工程已指定springBoot版本 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 因为我的配置文件是 bootstrap.yml 文件,spring boot版本高后不能自动读取需要这个依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!-- yml文件中无法通过lb 分发请求问题 解决依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2. 設定ファイル
server:
port: 8000 # 指定gateway网关服务端口
spring:
application:
name: spring-myself-gateway #拟定服务名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #nacos服务注册地址
gateway:
routes: #Routes 路由分发功能
- id: spring-myself-user #拟定路由名称,可任意。最好与对应服务,服务名称一致
uri: lb://spring-myself-user # lb:负载均衡。后面对应的那nacos注册服务名称。实则URL
predicates: #前言
- Path=/user/** #当我们请求gateway服务时前缀如果是这个就会转发上面uri
filters:
- StripPrefix=1 # 过滤到一层请求 也就是 /user/
# 我user服务模块端口是8001。 当我们请求 127.0.0.1:8000/user/System/doLogin 时他会通过网关进行转发,转发真实地址: 127.0.0.1:8001/System/doLogin
3 番目に、グローバル フィルターの使用
GateWay は、私たちのために GlobalFilter インターフェイスを密接に作成してくれました。すべてのリクエストのフィルタリングを完了するには、このインターフェイスを実装するだけで済みます。
コード:
ゲートウェイ プロジェクトに対応するフィルター パッケージを作成します。すべてのフィルターを書き込むために使用されます。
@Component //注入容器
@Slf4j //日志打印(需要Lombok依赖) 全局过滤,优先等级(值越小越先执行)
public class TestFilter implements GlobalFilter, Ordered {
//GlobalFilter接口的重写方法
@Override //入参理解: 本次请求交互信息,request等 管道
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//根据实际业务条件判断此请求是否继续执行
if(1==1){
//return chain.filter(exchange) 正常执行请求
return chain.filter(exchange);
}
//返回null则是对此请求做了过滤,无效了。
return null;
}
//Ordered接口重写,返回int值,值越小越先执行
@Override
public int getOrder() {
return -1;
}
}
このようなグローバルフィルターが記述されます。実際のビジネスに応じて対応リリースとフィルタリングを実行
// インタラクション情報からリクエストを取得 ServerHttpRequest request =exchange.getRequest();// インタラクション情報からレスポンスを取得します
ServerHttpResponse 応答 = Exchange.getResponse();//例: 取引所からトークン情報を取得する
文字列トークン =exchange.getRequest().getHeaders().getFirst("トークン");
アクセス制御(ブラック&ホワイトリスト)
プロジェクト内の一部のリクエストは、そのようなインターフェイスの権限フィルタリングによりメイン プロセスが失敗するため、権限フィルタリングを必要としません。登録、ログイン、その他のインターフェイスなど。すべての権限とトークンを持っているのに登録しているのに、なぜログインするのでしょうか? したがって、この時点で、yml ファイルでホワイトリスト URL を構成する必要があります。クラスで直接。yml。あるいはデータでも構いません。ホワイトリスト リスト コレクションを読み取ることができる限り、プロジェクトを確認します。通常、構成センターで構成され、サービスを再起動する必要がなく、管理に便利です。@ConfigurationProperties アノテーションを使用して yml ファイルから読み取り、現在の URL リクエストと比較し、一致する場合は、アクセス許可フィルターなしで直接解放されます。
グローバル フィルターを使用して、xss 攻撃、ブラックリスト、およびホワイトリストを防止できます。クロスドメイン情報を構成するには、WebFilter フィルターを介して実装する必要があります。
クロスドメイン構成: ruoyi-plusを参照してください。
@Component
public class GlobalCorsFilter implements WebFilter, Ordered {
/**
* 这里为支持的请求头,如果有自定义的header字段请自己添加
*/
private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Language, Content-Type, Authorization, credential, X-XSRF-TOKEN, isToken, token, Admin-Token, App-Token";
private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD";
private static final String ALLOWED_ORIGIN = "*";
private static final String ALLOWED_EXPOSE = "*";
private static final String MAX_AGE = "18000L";
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
if (CorsUtils.isCorsRequest(request)) {
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);
headers.add("Access-Control-Max-Age", MAX_AGE);
headers.add("Access-Control-Allow-Credentials", "true");
if (request.getMethod() == HttpMethod.OPTIONS) {
response.setStatusCode(HttpStatus.OK);
return Mono.empty();
}
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
要約:
実際、ゲートウェイに設定する必要がある機能は、上で説明した機能以外にもあります。ゲートウェイでの設定も面倒です。今の私の力では、うまく言うのは難しいです。学びながら学びましょう。