.net core 微服務之 Ocelot 集成 IdentityServer4

爲什麼集成在Ocelot中

在上一篇文章中,我們並沒有將認證授權集成在Ocelot中,在生產環境中,如果我們每個服務都添加了認證授權,那麼在實際部署中肯定會生成很多的配置,就會相對於麻煩。

所以我們就把IdentityServer4加到網關中,客戶端的請求通過網關就會進行身份證驗證,當網關的身份驗證通過之後就會把請求轉發給服務集羣中,集羣就不需要進行身份驗證了

 

項目示例

1. 在網關中引入包

IdentityServer4.AccessTokenValidation

2. 注入服務,這裏要在Idr4中新增一個網關的api資源名稱,我比較懶,就用的上篇文章創建好了的名稱。

注意,這裏要給一個Sceme名稱,隨便取一個就行,方便Ocelot識別

//添加idr4權限
services.AddAuthentication("Bearer")
    //給當前授權隨便起個名稱,方便集成到Ocelot裏面去
    .AddIdentityServerAuthentication("OcelotScheme",options =>
    {
        options.Authority = "http://localhost:2000"; //授權地址
        options.RequireHttpsMetadata = false; 
        options.ApiSecret = "testcode";  //網關資源API祕鑰
        options.ApiName = "signalrapi";  //網關的資源API名稱
    });

3. 新加一個測試的Ocelot配置文件 ocelot.Idr4.json , 在之前的路由(ReRoutes)中新增一個認證參數( AuthenticationOptions )配置就行了,這裏的 AuthenticationProviderKey 配置爲剛纔註冊服務時隨便取的那個Scheme名稱

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/ConsulHealthCheck/{action}", //下游轉發接口
      "DownstreamScheme": "http",


      "ServiceName": "consualapi",
      "LoadBalancerOptions": { //負載均衡配置
        "Type": "LeastConnection" //“輪詢”算法  可以配置其他的
      },
      "UpstreamPathTemplate": "/GateWay/{action}", //上游接口地址
      "UpstreamHttpMethod": [ "Get", "Post" ], //限制網關http請求方式
      //集成idr4認證
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "OcelotScheme",  //配置startup中服務名稱
        "AllowedScopes": []
      }
    }
  ],

  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    },
    "RateLimitOptions": {
      "DisableRateLimitHeaders": false,
      "QuotaExceededMessage": "Custom Tips",
      "HttpStatusCode": 999,
      "ClientIdHeader": "Test"
    }
  }
}

4. 在Consul服務中新增一個接口測試

/// <summary>
/// 當前登錄用戶信息
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
[HttpGet("UserInfo")]
public async Task<IActionResult> UserInfo()
{
    //根據網關轉發過來的token去認證服務獲取用戶信息
    var accessToken=HttpContext.Request.Headers["Authorization"].ToString();
    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri("http://localhost:2000");
    client.DefaultRequestHeaders.Add("Authorization", accessToken);
    var userinfo = await client.GetAsync("/connect/userinfo");

    return Ok($"你正在調用端口號爲{Request.HttpContext.Connection.LocalPort}的方法, 用戶信息爲 { userinfo.Content.ReadAsStringAsync().Result}");
}

運行效果

 

Ocelot實現 動態路由

 如果添加很多個服務,那麼會產生很多的Ocelot.xx.json文件,這裏就使用動態路由,只有一個Ocelot.json文件。

1. 添加一個動態路由的Json文件( DynamicReOcelot.json ),ReRoutes 和  Aggregates 一定要爲空

{
  "ReRoutes": [],
  "Aggregates": [],
   //單個服務配置限流
  "DynamicReRoutes": [
    {
      "ServiceName": "consualapi",
      "RateLimitRule": {
        "ClientWhitelist": [],
        "EnableRateLimiting": true,
        "Period": "1s",
        "PeriodTimespan": 3000,
        "Limit": 3
      }
    }
  ],
  "GlobalConfiguration": {
    "RequestIdKey": null,
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul",
      "Token": null,
      "ConfigurationKey": null
    },
    "RateLimitOptions": {
      "ClientIdHeader": "ClientId",
      "QuotaExceededMessage": null,
      "RateLimitCounterPrefix": "ocelot",
      "DisableRateLimitHeaders": false,
      "HttpStatusCode": 429
    },
    "QoSOptions": {
      "ExceptionsAllowedBeforeBreaking": 0,
      "DurationOfBreak": 0,
      "TimeoutValue": 0
    },
    "BaseUrl": null,
    "LoadBalancerOptions": {
      "Type": "LeastConnection",
      "Key": null,
      "Expiry": 0
    },
    "DownstreamScheme": "http",
    "HttpHandlerOptions": {
      "AllowAutoRedirect": false,
      "UseCookieContainer": false,
      "UseTracing": false
    },
    //集成idr4認證
    "AuthenticationOptions": {
      "AuthenticationProviderKey": "OcelotScheme", //配置startup中服務名稱
      "AllowedScopes": []
    }
  }
}

 

 

 

2. 加載動態路由配置文件,替代之前的Ocelot.json文件

 public static IHostBuilder CreateHostBuilder(string[] args) =>
     Host.CreateDefaultBuilder(args)
         .ConfigureWebHostDefaults(webBuilder =>
         {
             webBuilder.UseStartup<Startup>();
             webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
             {
                 // 1、加載ocelot配置文件
                 //config.AddJsonFile("ocelot.json");
                 

                 //2. 動態加載多個服務配置
                 //config
                 //    .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                 //    .AddJsonFile("appsettings.json", true, true)
                 //   .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
                 //   .AddOcelot(hostingContext.HostingEnvironment)
                 //  .AddEnvironmentVariables();

                 //3. 動態路由 
                 config.AddJsonFile("DynamicReOcelot.json");
             });
         });

請求效果:

 

 

 

注意,這裏解析邏輯:

1. 客戶端發起請求到 http://localhost:7000 的網關

2. 網關在consul服務發現中找到對應的服務名稱,後隨機返回一個服務名稱的地址,這裏是 http://localhost:5004

3. 請求的路徑除了第一個是服務的名字,後面都是網關下游請求服務的地址,這裏是  /ConsulHealthCheck/userinfo

4. 所以實際的請求是 : http://localhost:5004/ConsulHealthCheck/userinfo

 

 

 

 

 

 

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