<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # **網關** ## 傳統的ESB企業總線 **滿足ESB的主要場景**? >一旦某個企業決定要走企業服務總線路線,他們通常會陷入幾大廠商的巨型軟件套件的復雜性(及成本)的深潭之中,這些廠商試圖將ESB模式等同于某個特定產品。而這些套件,雖然它們往往是比較全面的適配器,但其功能卻超出了一般企業的需要。當敏捷和客戶需求的響應速度作為架構目標時,答案絕不會是需要花一個星期去安裝的解決方案。它們是重量級的、適配器驅動的解決方案,通常需要數月才能建成具有一定價值的規模,而且協議映射和數據格式往往還需要許多編碼。此外,它們主要關注聯通性,而很少關心安全,性能等因素。 API網關產品隨著微服務概念出現并趨于成熟之后 ,用戶就會意識到這種輕量級、方便易用、廉價的替代方案能夠實現更多的傳統ESB平臺所提供的功能,而已經在實施的傳統ESB并非都取得了成功。此時一個需求分析問題就出現了,API網關能否滿足我的需求?如果可以的話,為什么還要繼續沿著原先那條更慢、更昂貴、更費勁的道路向相同的目標前進呢?API網關更易于配置,可易于擴展,而且從運維的角度看它更便于管理。它能為安全架構師、應用開發者、網絡管理員和運維人員都帶來價值;更重要的是,任何痛苦都痛不過口袋里缺錢。 ![](https://img.kancloud.cn/68/88/6888e32a4d6f4b31332dc02999bcdc2c_613x778.png) **應用形態的發展趨勢** >隨著蘋果公司2008年發布了App Store,擁有應用商店的智能手機很快就成為了主流趨勢。移動應用的開發變得司空見慣,但是應用程序本身能做的事情很少,它們需要與世界各地的數據進行交互。如果有簡單高效的方法來訪問其他企業提供的數據和功能,開發人員就可以開發出更強大的應用程序。除此之外,運行在瀏覽器中基于HTML/JavaScript開發的功能強大的單頁應用,甚至是傳統的MVC架構的服務器端web應用程序如今的運行形態也是不同的,這些應用通常會被部署到能夠彈性伸縮的云服務器上(Amazon Elastic Beanstalk),服務器內部不會存儲數據和狀態,幾乎每一個重要的用戶交互都需要由后端的API請求來支撐。 **ESB無法支撐當今應用形態** >企業早期的web應用體系架構要么簡單的數據庫訪問類應用,要么是通過ESB進行服務集成的面向服務的架構。如果基于ESB的面向服務的架構,無論是soap類型服務還是其他標準的服務,它們最初的主要消費者都來源于企業內部的系統,通常數據是以XML形式進行傳輸,對于企業內部的高速網絡的影響很小,同時由于內部系統之間都是相互信任不需要考慮太多的安全因素,所以許多架構師將ESB作為面向服務架構最合理高效的最佳實踐。但是對于移動應用、具有彈性云能力的高度可伸縮的web應用來說,ESB并不能滿足它們的需求,因為ESB設計初衷并不是為了適應這種高并發、高性能、頻繁和服務器進行交互的應用。并且大多數場景,這些應用都運行在企業的安全防線之外,需要將企業的服務通過公共媒體(如Internet)進行公開,這就意味著企業需要關心從各種各樣的有效負載攻擊(如XML威脅)到影響吞吐量和連接的拒絕服務攻擊等一系列新的安全風險,同時還必須提供一種有效可靠的手段可以認證接入的應用程序,以便有效地控制其服務訪問權限。 **api-gateway** >api-gateway是一款輕量級、高性能、易擴展的基于zuul的網關產品,提供API的統一管理服務、涵蓋API發布、管理、運維的全生命周期管理。對內輔助用戶簡單、快速、低成本、低風險的實現微服務聚合、前后端分離、系統集成等功能;對外面向合作伙伴、開發者開放服務。通過使用API-Gateway,我們能快速幫助用戶實現傳統ESB面臨的主要場景,又能滿足新型業務場景(移動應用等)所需的高性能、安全、可靠等要求。 ![](https://img.kancloud.cn/31/6d/316d77a699b9df478e8741d809b4fa9b_650x287.png) ## 通用網關設計 ![](https://img.kancloud.cn/1e/62/1e628e93dd065657ab37b7547fb36ebc_1013x680.png) ## 軟負載ZUUL ![](https://img.kancloud.cn/7a/d3/7ad38b1114e34924cfe3b392383b894b_1032x574.png) ## api-gateway在項目中的位置 ![](https://img.kancloud.cn/fe/7a/fe7ac9108d57ec9d64e8d7d55fe5763b_1006x660.png) ## API Gateway 作用 * 簡化客戶端調用復雜度 在微服務架構模式下后端服務的實例數一般是動態的,對于客戶端而言,很難發現動態改變的服務實例的訪問地址信息。因此在基于微服務的項目中為了簡化前端的調用邏輯,通常會引入API Gateway作為輕量級網關,同時API Gateway中也會實現相關的認證邏輯從而簡化內部服務之間相互調用的復雜度。 ![](https://img.kancloud.cn/be/30/be3023b48d1850fc3dc786eb6ef0a4e0_401x346.png) * 數據裁剪以及聚合 通常而言不同的客戶端在顯示時對于數據的需求是不一致的,比如手機端或者Web端又或者在低延遲的網絡環境或者高延遲的網絡環境。因此為了優化客戶端的使用體驗,API Gateway可以對通用性的響應數據進行裁剪以適應不同客戶端的使用需求,同時還可以將多個API調用邏輯進行聚合,從而減少客戶端的請求數,優化客戶端用戶體驗。 * 多渠道支持 當然我們還可以針對不同的渠道和客戶端提供不同的API Gateway,對于該模式的使用由另外一個大家熟知的方式叫Backend for front-end,在Backend for front-end模式當中,我們可以針對不同的客戶端分別創建其BFF。 ![](https://img.kancloud.cn/37/7e/377e2cebc23913a3e3d136450f170545_688x399.png) * 遺留系統的微服務改造 對于遺留系統而言進行微服務改造通常是由于原有的系統存在或多或少的問題,比如技術債務,代碼質量,可維護性,可擴展性等等。API Gateway的模式同樣適用于這一類遺留系統的改造,通過微服務化的改造逐步實現對原有系統中的問題的修復,從而提升對于原有業務相應力的提升。通過引入抽象層,逐步使用新的實現替換舊的實現。 ![](https://img.kancloud.cn/0b/1a/0b1a6ddf8ef97aea17d8b96af9cb75c1_645x361.png) 在Spring Cloud體系中,Spring Cloud Zuul就是提供負載均衡,反向代理,權限認證的一個API Gateway。 # api-gateway代碼分析 ## 開啟ZUUL ![](https://box.kancloud.cn/d0d1f3b21523120ba677a274168f44e7_1731x534.png) ## 網關的2層超時調優 ``` #設置最大容錯超時時間 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 90000 #設置最大超時時間 ribbon: eager-load: enabled: true ServerListRefreshInterval: 10 #刷新服務列表源的間隔時間 httpclient: enabled: false okhttp: enabled: true ReadTimeout: 90000 ConnectTimeout: 90000 OkToRetryOnAllOperations: true MaxAutoRetries: 1 MaxAutoRetriesNextServer: 1 ``` ![](https://img.kancloud.cn/39/37/3937fb3c071e84009e7e7e1d70f75cd1_1032x459.png) ## 網關自定義過濾器 ![](https://img.kancloud.cn/cc/66/cc6672a18ecfb8bd0d5a0e370daa6bfc_606x609.png) * brave.servlet.TracingFilter :生成traceId * com.open.capacity.common.filter.TraceContextFilter:傳遞traceId * com.open.capacity.client.filter.AccessFilter:傳遞token * com.open.capacity.client.filter.RequestFilter::傳遞traceId * com.open.capacity.client.filter.ResponseFilter:響應頭增加traceId ## api-gateway 構建資源服務器 ``` <!-- 資源服務器 --> <dependency> <groupId>com.open.capacity</groupId> <artifactId>security-core</artifactId> <version>${core.version}</version> </dependency> ``` [security-core源碼分析](http://www.hmoore.net/owenwangwen/open-capacity-platform/1048267) ## 資源服務器認證處理流程圖 ![](https://box.kancloud.cn/7eea410bb58d317640e825e7a3e7c20e_588x703.png) ## 網關白名單 ``` security: oauth2: ignored: /test163/** , /api-auth/** , /doc.html ,/test111 ,/api-user/users-anon/login, /api-user/users/save, /user-center/users-anon/login,/document.html,**/v2/api-docs,/oauth/** ,/login.html ,/user/login,/**/**.css ,/**/**.js ,/getVersion token: store: type: redis ``` ## 認證核心代碼 ``` public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (authentication == null) { throw new InvalidTokenException("Invalid token (token not found)"); } String token = (String) authentication.getPrincipal(); OAuth2Authentication auth = tokenServices.loadAuthentication(token); if (auth == null) { throw new InvalidTokenException("Invalid token: " + token); } Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds(); if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) { throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")"); } checkClientDetails(auth); if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) { OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails(); // Guard against a cached copy of the same details if (!details.equals(auth.getDetails())) { // Preserve the authentication details from the one loaded by token services details.setDecodedDetails(auth.getDetails()); } } auth.setDetails(authentication.getDetails()); auth.setAuthenticated(true); return auth; ``` ### 授權流程 ![](https://box.kancloud.cn/53e8ffda6d12e4d48acdc6231bdafc4e_1408x773.png) #### 啟用授權 ![](https://box.kancloud.cn/feb228e1dd210009a0d4f57779cdb44b_1792x355.png) ``` @Bean public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) { OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler(); expressionHandler.setApplicationContext(applicationContext); return expressionHandler; } ``` # 網關api權限設計 ![](https://img.kancloud.cn/c1/68/c1685025219f816bb33f1840592b5599_855x351.png) 相同用戶,不同應用的權限隔離 客戶端模式 : 客戶端A 申請的token ,可以訪問/api-user/menu/current , 客戶端B 申請的token,不讓訪問/api-user/menu/current 密碼模式: 客戶端模式 : 客戶端A admin用戶 申請的token ,可以訪問/api-user/menu/current , 客戶端B admin用戶 申請的token,不讓訪問/api-user/menu/current 參考issue:[https://gitee.com/owenwangwen/open-capacity-platform/issues/IRG23]() 網關是否開啟基于應用隔離,代碼注釋了,只是基于token的合法性校驗,按建議開啟是否啟用api接口服務權限 OpenAuthorizeConfigManager > 游樂場買了通票,有些地方可以隨便玩,有些地方另外 > 單獨校驗買票 > config.anyRequest().authenticated() ; > //這種通票,token校驗正確訪問 > config.anyRequest().access("@rbacService.hasPermission(request, authentication)"); //這種另外 > 單獨校驗,適用于網關對api權限校驗 ``` ~~~ /** * @author 作者 owen E-mail: 624191343@qq.com * @version 創建時間:2018年2月1日 下午9:50:27 * 類說明 */ @Component public class OpenAuthorizeConfigManager implements AuthorizeConfigManager { @Autowired private List<AuthorizeConfigProvider> authorizeConfigProviders; @Autowired(required=false) private RbacService rbacService ; /* (non-Javadoc) * @see com.imooc.security.core.authorize.AuthorizeConfigManager#config(org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry) */ @Override public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) { //設置訪問 for (AuthorizeConfigProvider authorizeConfigProvider : authorizeConfigProviders) { authorizeConfigProvider.config(config) ; } //token正確登錄 config.anyRequest().authenticated() ; if(rbacService!=null){ // 放開則全部可以不需要認證訪問 config .anyRequest() .access("@rbacService.hasPermission(request, authentication)"); } } } ~~~ ``` 通過clientID隔離服務權限 ![](https://img.kancloud.cn/ad/52/ad52f219fbe2312c95e970d91b7975d9_564x443.png) ``` ~~~ //package com.open.capacity.client.service; ///** // * // */ // //import java.util.Iterator; //import java.util.List; //import java.util.Map; // //import javax.annotation.Resource; //import javax.servlet.http.HttpServletRequest; // //import org.springframework.security.core.Authentication; //import org.springframework.security.core.context.SecurityContextHolder; //import org.springframework.security.oauth2.provider.OAuth2Authentication; //import org.springframework.stereotype.Service; //import org.springframework.util.AntPathMatcher; // //import com.open.capacity.client.dao.SysClientDao; //import com.open.capacity.client.dao.SysServiceDao; //import com.open.capacity.client.oauth2.service.RbacService; // ///** // * API 級別權限認證 // * // * @author 作者 owen E-mail: 624191343@qq.com // * @version 創建時間:2017年12月4日 下午5:32:29 // * 類說明 // */ // //@Service("rbacService") //public class RbacServiceImpl implements RbacService { // // @Resource // private SysServiceDao sysServiceDao; // // @Resource // private SysClientDao sysClientDao; // // private AntPathMatcher antPathMatcher = new AntPathMatcher(); // // /** // * @param request HttpServletRequest // * @param authentication 認證信息 // * @return 是否有權限 // */ // @Override // public boolean hasPermission(HttpServletRequest request, Authentication authentication) { // // Authentication user = SecurityContextHolder.getContext() // .getAuthentication(); // // //TODO 目前都是true // boolean hasPermission = false; // // if (user != null) { // // if (user instanceof OAuth2Authentication) { // // OAuth2Authentication athentication = (OAuth2Authentication) user; // // String clientId = athentication.getOAuth2Request().getClientId(); // // Map map = sysClientDao.getClient(clientId); // // if (map == null) { // return false; // } else { // List<Map> list = sysServiceDao.listByClientId(Long.valueOf(String.valueOf(map.get("id")))); // ; // // for (Iterator<Map> it = list.iterator(); it.hasNext(); ) { // Map temp = it.next(); // // if (antPathMatcher.match( String.valueOf(temp.get("path")),request.getRequestURI())) { // return true; // } // } // return false; // } // // // } // // } // // // // // // // return hasPermission; // } // //} ~~~ ``` ![](https://img.kancloud.cn/b6/83/b683a46fc26574701dfa977e6fe3f243_916x418.png) # 源碼分析 ## zuul內部代碼 ![](https://img.kancloud.cn/de/dc/dedc89358d3836b8e5255e4136eaccfa_1324x754.png) ![](https://img.kancloud.cn/6f/2d/6f2d0acd62574814c9303f4414985edb_1310x361.png) ![](https://img.kancloud.cn/f0/6f/f06f9d5fce900fbac3d437e0331321cd_1244x652.png) 參考:https://www.jianshu.com/p/295e51bc1518 ## zuul基于eureka的服務發現路由 org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator ![](https://box.kancloud.cn/f750026dbf93181e86d923c36858d5f3_1515x744.png) ## 生產軟負載NGINX構建ZUUL集群 ![](https://img.kancloud.cn/9d/1e/9d1e85073fa1ba4ed17e5587cede9e1f_632x349.png) ## pom核心依賴 ![](https://box.kancloud.cn/23e4d4f05c60def0982a1189c63340f2_1754x685.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看