[轉載]Ocelot簡易教程(五)之集成IdentityServer認證以及受權

做者:依樂祝
原文地址:http://www.javashuo.com/article/p-bycbsvjo-x.htmljavascript

 

最近比較懶,因此隔了N天才來繼續更新第五篇Ocelot簡易教程,本篇教程會先簡單介紹下官方文檔記錄的內容而後在前幾篇文檔代碼的基礎上進行實例的演示。目的是爲了讓小白也能按照步驟把代碼跑起來。固然,在開始以前你要對IdentityServer有必定的瞭解,而且可以進行IdentityServer的集成,若是你還不會集成IdentityServer的話仍是先看看個人這篇Asp.NetCoreWebApi圖片上傳接口(二)集成IdentityServer4受權訪問(附源碼)文章吧。裏面有一步一步的集成IdentityServer的實例。html

好了,廢話說完了,那就讓咱們開始進入今天的主題吧!Ocelot認證與受權。java

概念表述

認證

爲了驗證ReRoutes並隨後使用Ocelot的任何基於聲明的功能,例如受權或使用令牌中的值修改請求。 用戶必須像往常同樣在他們的Startup.cs中註冊認證服務,唯一的不一樣是他們須要給每一個認證註冊提供一個方案,例如git

public void ConfigureServices(IServiceCollection services) {
    var authenticationProviderKey = "OcelotKey";

    services.AddAuthentication()
        .AddJwtBearer(authenticationProviderKey, x =>
        {
        });
}

在此示例中,OcelotKey是此提供程序已註冊的方案。而後咱們將其映射到配置中的ReRoute,例如github

"ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 1001
        },
        {
          "Host": "localhost",
          "Port": 1002
        }
      ],
      "UpstreamPathTemplate": "/{everything}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "OcelotKey",
        "AllowedScopes": []
      }
    }
  ]

當Ocelot運行時,它將查看此ReRoutes中 AuthenticationOptions節點下面的AuthenticationProviderKey並檢查是否有使用給定密鑰註冊的身份驗證提供程序。若是沒有,那麼Ocelot不會啓動,若是有的話ReRoute將在執行時使用該提供者。web

若是對ReRoute進行了身份驗證,則Ocelot將在執行身份驗證中間件時調用與其關聯的認證方案。若是請求失敗,則認證Ocelot返回http的狀態代碼爲401即未受權狀態。sql

JWT令牌

若是您想使用JWT令牌進行身份驗證,可能來自OAuth之類的提供程序,您能夠正常註冊您的身份驗證中間件,例如數據庫

public void ConfigureServices(IServiceCollection services) {
    var authenticationProviderKey = "OcelotKey";

    services.AddAuthentication()
        .AddJwtBearer(authenticationProviderKey, x =>
        {
            x.Authority = "test";
            x.Audience = "test";
        });

    services.AddOcelot();
}

而後將身份驗證提供程序密鑰映射到配置中的ReRoute,例如json

"ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 1001
        },
        {
          "Host": "localhost",
          "Port": 1002
        }
      ],
      "UpstreamPathTemplate": "/{everything}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "OcelotKey",
        "AllowedScopes": []
      }
    }
  ]

Identity Server Bearer Tokens認證

接下來上今天的主角了。identityServer認證方式。爲了使用IdentityServer承載令牌,請按照慣例在ConfigureServices 中使用方案(密鑰)註冊您的IdentityServer服務。 若是您不明白如何操做,請訪問IdentityServer文檔。或者查看個人這篇Asp.NetCoreWebApi圖片上傳接口(二)集成IdentityServer4受權訪問(附源碼)文章。c#

var authenticationProviderKey = "OcelotKey";
            var identityServerOptions = new IdentityServerOptions();
            Configuration.Bind("IdentityServerOptions", identityServerOptions);
            services.AddAuthentication(identityServerOptions.IdentityScheme)
                .AddIdentityServerAuthentication(authenticationProviderKey, options =>
                {
                    options.RequireHttpsMetadata = false; //是否啓用https
                    options.Authority = $"http://{identityServerOptions.ServerIP}:{identityServerOptions.ServerPort}";//配置受權認證的地址
                    options.ApiName = identityServerOptions.ResourceName; //資源名稱,跟認證服務中註冊的資源列表名稱中的apiResource一致
                    options.SupportedTokens = SupportedTokens.Both;
                }
                );
            services.AddOcelot()//注入Ocelot服務
                    .AddConsul();

而後將身份驗證提供程序密鑰映射到配置中的ReRoute,例如

"ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 1001
        },
        {
          "Host": "localhost",
          "Port": 1002
        }
      ],
      "UpstreamPathTemplate": "/{everything}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "OcelotKey",
        "AllowedScopes": []
      }
    }
  ]

容許訪問的範圍(Allowed Scopes)

若是將範圍添加到AllowedScopes,Ocelot將得到類型範圍的全部用戶聲明(從令牌中),並確保用戶具備列表中的全部範圍。

這是一種基於範圍限制對ReRoute訪問的方式。(我也沒用過這種方式,感受有點相似IdentityServer Scope的概念)

實例演示集成IdentityServer

  1. 新建一個OcelotDemo.Auth asp.net core web api項目

  2. 項目進行IdentityServer服務端相關的配置,這裏爲了演示的方便採用硬編碼的方式進行的配置。具體配置能夠參考Asp.NetCoreWebApi圖片上傳接口(二)集成IdentityServer4受權訪問(附源碼)這篇文章

  3. 在網關項目OcelotDemo中添加Nuget包

    Install-Package IdentityServer4.AccessTokenValidation
  4. 在OcelotDemo項目中的Startup.cs中加入identityServer驗證,以下所示:

    var authenticationProviderKey = "OcelotKey";
                var identityServerOptions = new IdentityServerOptions();
                Configuration.Bind("IdentityServerOptions", identityServerOptions);
                services.AddAuthentication(identityServerOptions.IdentityScheme)
                    .AddIdentityServerAuthentication(authenticationProviderKey, options =>
                    {
                        options.RequireHttpsMetadata = false; //是否啓用https
                        options.Authority = $"http://{identityServerOptions.ServerIP}:{identityServerOptions.ServerPort}";//配置受權認證的地址
                        options.ApiName = identityServerOptions.ResourceName; //資源名稱,跟認證服務中註冊的資源列表名稱中的apiResource一致
                        options.SupportedTokens = SupportedTokens.Both;
                    }
                    );
                services.AddOcelot()//注入Ocelot服務
                        .AddConsul();
  5. 在ocelot.json中須要加入驗證的ReRoute中,修改成以下的配置代碼:

    "ReRoutes": [
        {
          "DownstreamPathTemplate": "/api/{everything}",
          "DownstreamScheme": "http",
          "DownstreamHostAndPorts": [
            {
              "Host": "localhost",
              "Port": 1001
            },
            {
              "Host": "localhost",
              "Port": 1002
            }
          ],
          "UpstreamPathTemplate": "/{everything}",
          "UpstreamHttpMethod": [ "Get", "Post" ],
          "LoadBalancerOptions": {
            "Type": "RoundRobin"
          },
          "AuthenticationOptions": {
            "AuthenticationProviderKey": "OcelotKey",
            "AllowedScopes": []
          }
        }
      ]
  6. 打開PostMan測試一下代碼吧,首先訪問一下http://localhost:1000/values 這時候返回的結果是401未受權的狀態,以下圖所示:

    1539780575952

  7. 而後訪問咱們上面新建的IdentityServer服務器並獲取Token。以下圖所示配置對應的參數進行獲取:

    1539780272769

  8. 而後使用咱們獲取到的access_token進行Ocelot網關接口的訪問,以下所示進行配置:

    1539780805247

    能夠看到結果返回了200代碼,而且結果在Good以及Order之間進行切換。由於Ocelot.json文件中對路由進行了RoundRobin的負載均衡的策略。

受權

Ocelot支持基於聲明的受權,該受權在身份驗證後運行。這意味着若是您有要受權的Url,則能夠將如下內容添加到ReRoute配置中。

"RouteClaimsRequirement": {
    "UserType": "registered"
}

在此示例中,當調用受權中間件時,Ocelot將檢查用戶是否具備聲明類型UserType以及是否已註冊該聲明的值。若是不是,則用戶將不被受權,而且將響應403禁止訪問的狀態碼。

固然這種受權的方式在大部分業務場景中都是不適用的,須要本身重寫Ocelot的中間件才能實現。經過Ocelot中間件的重寫你能夠實現本身的受權邏輯,若是你還有限流的需求,好比說對每一個客戶端進行不一樣的限流策略。比方說,有三個客戶端A,B,C。訪問相同的URL,可是咱們要控制A,每分鐘只能訪問10次,B每分鐘能訪問20次,而C不容許訪問。針對這個場景Ocelot卻沒有相關的實現。可是咱們能夠經過重寫Ocelot中間件來實現它。因爲篇幅有限,因此今天就不進行介紹了。可是我會抽時間進行相關的實現,並分享給你們。

源碼

本篇博文的源碼已經上傳到Github。能夠進行參考。https://github.com/yilezhu/OcelotDemo

總結

本文先大體介紹一下Ocelot如何集成認證受權,而後經過實例進行了IdentityServer集成的演示,但願能對你們有必定的參考做用。固然文中也提到了,應對複雜的受權以及限流須要自行重寫Ocelot中間件進行實現。具體如何實現呢,我會盡快分享給你們。一樣的經過重寫Ocelot中間件咱們還能夠把ocelot.json的配置信息存儲到數據庫並緩存到Redis中!最後,感謝你們的閱讀!

做者:依樂祝

出處:https://www.cnblogs.com/yilezhu

聯繫:1015657114@qq.com .NET Core實戰項目交流羣:637326624

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。若有問題或建議,請多多賜教,很是感謝。
DotNetCore實戰
相關文章
相關標籤/搜索