Portal-Gateway路由網關

1.1整體設計

 

  • Portal-Gateway的應用場景:用戶已登錄,請求其他服務。
  • 客戶端的請求到達網關,網關會調用gateway系統進行請求身份合法性的驗證:
  1. 驗證不通則直接拒絕,並返回401;
  2. 如果通過驗證,則轉發到具體服務。

Portal-Gateway的架構圖如下所示:

微服務架構權限 (1).png


1.2 gateway實現

主要實現的功能有:

    • 區分暴露接口(即對外直接訪問)和需要合法身份登錄之後才能訪問的接口
    • 需要合法身份登錄之後才能訪問的接口,根據傳入的Access token進行構造頭部,頭部主要包括userId等信息,可根據自己的實際業務在auth服務中進行設置。
    • 需要暴露接口設置permitAll(),其餘接口進入身份合法性校驗的流程,調用auth服務,如果通過則正常繼續轉發,否則拋出異常,返回401。

繪製的流程圖如下:

微信截圖_20200311190742.png


1.2.1 permitAll實現

對外暴露的接口可以直接訪問,這可以依賴配置文件,而配置文件又可以通過配置中心進行動態更新,所以不用擔心有hard-code的問題。經過permitall配置的路徑

在配置文件中定義需要permitall的路徑:

 

auth:
  permitall:
    -
      pattern: /login/**
    -
      pattern: /web/public/**

 

 

服務啓動時,讀入相應的Configuration,下面的配置屬性讀取以auth開頭的配置:

 

@Bean
@ConfigurationProperties(prefix = "auth")
public PermitAllUrlProperties getPermitAllUrlProperties() {
    return new PermitAllUrlProperties();
}

 


1.2.2 自定義RemoteTokenServices實現

ResourceServerTokenServices接口其中的一個實現是RemoteTokenServices

RemoteTokenServices主要是查詢auth服務的/check_token端點以獲取一個token的校驗結果。如果有錯誤,則說明token是不合法的。Spring Cloud Security添加如下默認配置,對應auth服務中的相應端點。

 

properties: 
    sso: 
        loginUrl: https://myrtc.egoonet.com/sso    # 單點登錄地址  
        ssoInternal: https://myrtc.egoonet.com/sso # 單點中心內網負載地址,SAML協議可不填
    security:
        oauth2:
          client:
              client-id: portal                    # 客戶端ID (單點中心提供)      
              client-secret: oauth_client_secret   # 客戶端祕鑰 (單點中心提供)     
          resource:
              user-info-uri: ${properties.sso.loginUrl}/if/sso/user/me       # 獲取當前用戶信息地址
              token-info-uri: ${properties.sso.ssoInternal}/oauth/check_token# 驗證token地址

 


1.2.3 Router的實現

詞彙表主要包含以下3個組成部分:

  • Route 路由:gateway的基本構建模塊。它由ID、目標URI、斷言集合和過濾器集合組成。如果聚合斷言結果爲真,則匹配到該路由。
  • Predicate 斷言:這是一個Java 8 Function Predicate。輸入類型是 Spring Framework ServerWebExchange。這允許開發人員可以匹配來自HTTP請求的任何內容,例如Header或參數。
  • Filter 過濾器:這些是使用特定工廠構建的 Spring FrameworkGatewayFilter實例。所以可以在返回請求之前或之後修改請求和響應的內容。

 

oskz0s4hwt.png

客戶端向Spring Cloud Gateway發出請求。如果Gateway Handler Mapping確定請求與路由匹配,則將其發送到Gateway Web Handler。此handler通過特定於該請求的過濾器鏈處理請求。圖中filters被虛線劃分的原因是filters可以在發送代理請求之前或之後執行邏輯。先執行所有“pre filter”邏輯,然後進行請求代理。在請求代理執行完後,執行“post filter”邏輯。

 

路由規則都可以配置,具體使用可以參考一下Spring Cloud Gateway 2.1.0 中文官網文檔


1.3 gateway配置和使用

由於項目使用maven模塊化配置,Springboot版本爲:2.1.3.RELEASE, SpringCloud版本爲:Finchley.RELEASE。

gateway支持兩種方式提供路由服務,其一是配置文件啓用,其二則是通過代碼達到目的。


1.3.1 pom配置

要在項目中引入gateway,需要引用 group  org.springframework.cloud 和 artifact id爲spring-cloud-starter-gateway starter。最新的Spring Cloud Release 構建信息,請參閱Spring Cloud Project page

如果應用了該starter,但由於某種原因不希望啓用網關,請進行設spring.cloud.gateway.enabled=false

重要 Spring Cloud Gateway依賴Spring Boot和Spring Webflux提供的Netty runtime。它不能在傳統的Servlet容器中工作或構建爲WAR

請注意:不要引入spring-boot-starter-web包,會導致Gateway啓動拋出異常


1.3.2 application.yml配置實現

spring:
  cloud:
    gateway:
      routes:
      # This route rule used to forward request to activity server
      - id: activity-route
        uri: lb://activity
        predicates:
        - Path=/activity/**
        filters:
        - StripPrefix=1

注意:Gateway默認轉發是全路徑的,設置StripPrefix=1表示從二級url路徑轉發,即http://localhost:port/activity/test將會轉發到http://{activity}/test


1.3.2 代碼實現

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/activity/**")
                        .filters(f -> f.stripPrefix(1).filter(new TestGetWayFilter()).addResponseHeader("X-Response-Default-Foo", "Default-Bar"))
                        .uri("lb://activity")
                        .order(0)
                        .id("activity-route")
                )
                .build();
 }

1.4 應用案例

1.4.1 案例1-通過使用Java正則表達式靈活地重寫請求路徑

包含一個 regexp正則表達式參數和一個 replacement 參數. 通過使用Java正則表達式靈活地重寫請求路徑。

對於請求路徑/foo/bar,將在發出下游請求之前將路徑設置爲/bar。注意,由於YAML規範,請使用 $\替換 $

cloud:
    gateway:
        routes:
             - id: service_path_route
               uri: http://222.73.213.174:10013
               predicates:
                - Path=/foo/**
               filters:
                - RewritePath=/foo/(?<segment>.*), /$\{segment}

 

該配置主要包含id、uri、predicates和fileters。

實現功能:

    1. 接口請求Potal-Gateway:http://ip:9099/foo/v1/WorkOrder/select
    2. 路徑中包含foo,Potal-Gateway會對foo進行過濾,使用fileters中的規則對其進行url替換
    3. 最終由Potal-Gateway轉發地址請求:http://222.73.213.174:10013/v1/WorkOrder/select

1.4.2 案例2-Cookie 路由斷言 Factory

Cookie 路由斷言 Factory有兩個參數,cookie名稱和正則表達式。請求包含次cookie名稱且正則表達式爲真的將會被匹配。

application.yml
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: http://example.org
        predicates:
        - Cookie=chocolate, ch.p

 

1.4.3 案例3-Header  路由斷言 Factory

 

Header 路由斷言 Factory有兩個參數,header名稱和正則表達式。請求包含次header名稱且正則表達式爲真的將會被匹配。

application.yml.
spring:
 cloud:
   gateway:
     routes:
     - id: header_route
       uri: http://example.org
       predicates:
       - Header=X-Request-Id, \d+

 

1.4.4 案例4-路由斷言 Factory

Host 路由斷言 Factory包括一個參數:host name列表。使用Ant路徑匹配規則,.作爲分隔符。

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

 

1.4.5 案例5-Method 路由斷言 Factory

Method 路由斷言 Factory只包含一個參數: 需要匹配的HTTP請求方式

application.yml.
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: http://example.org
        predicates:
        - Method=GET

所有GET請求都將被路由


 

1.4.6 案例6-Path 路由斷言 Factory

Path 路由斷言 Factory 有2個參數: 一個Spring PathMatcher表達式列表和可選matchOptionalTrailingSeparator標識 .

application.yml.
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://example.org
        predicates:
        - Path=/foo/{segment},/bar/{segment}

例如: /foo/1 or /foo/bar or /bar/baz的請求都將被匹配

URI 模板變量 (如上例中的 segment ) 將以Map的方式保存於ServerWebExchange.getAttributes() key爲ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE. 這些值將在GatewayFilter Factories使用以下方法來更方便地訪問這些變量。

Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");

 

1.4.7 案例7-Query 路由斷言 Factory

Query 路由斷言 Factory 有2個參數: 必選項 param 和可選項 regexp.

application.yml.
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://example.org
        predicates:
        - Query=baz

則包含了請求參數 baz的都將被匹配。

application.yml.
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://example.org
        predicates:
        - Query=foo, ba.

 

 

如果請求參數裏包含foo參數,並且值匹配爲ba. 表達式,則將會被路由,如:bar and baz

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章