• netCore微服务学习笔记(二):NetCore Ocelot Api网关


    一.API网关

      API网关是微服务架构中的唯一入口,它提供一个单独且统一的API入口用于访问内部一个或多个API。API 网关会拦截所有传入的请求,然后通过 API 管理系统(该系统负责处理各种必要的功能)将其发送出去。具有一些常见的功能包括:身份验证、路由、负载均衡、缓存、熔断限流等;

    二.Ocelot简介

      Ocelot是.net下开源的API网关,它实现了包括路由,认证、授权、服务发现、负载均衡、限流熔断等功能;具体可以参照文档Ocelot;Ocelot各个功能的实现,都是通过json配置文件来实现的,配置文件基本格式如下:

    {
        "Routes": [],
        "GlobalConfiguration": {}
    }
    配置信息包含两部分,一组路由,一个全局配置;路由作用是告诉Ocelot如何处理上游请求的对象。全局配置允许覆盖特定于路由的设置。
    关于详细的配置文件,信息如下:
     1 {
     2           "DownstreamPathTemplate": "/",
     3           "UpstreamPathTemplate": "/",
     4           "UpstreamHttpMethod": [
     5               "Get"
     6           ],
     7           "DownstreamHttpMethod": "",
     8           "DownstreamHttpVersion": "",
     9           "AddHeadersToRequest": {},
    10           "AddClaimsToRequest": {},
    11           "RouteClaimsRequirement": {},
    12           "AddQueriesToRequest": {},
    13           "RequestIdKey": "",
    14           "FileCacheOptions": {
    15               "TtlSeconds": 0,
    16               "Region": ""
    17           },
    18           "RouteIsCaseSensitive": false,
    19           "ServiceName": "",
    20           "DownstreamScheme": "http",
    21           "DownstreamHostAndPorts": [
    22               {
    23                   "Host": "localhost",
    24                   "Port": 51876,
    25               }
    26           ],
    27           "QoSOptions": {//熔断
    28               "ExceptionsAllowedBeforeBreaking": 0,
    29               "DurationOfBreak": 0,
    30               "TimeoutValue": 0
    31           },
    32           "LoadBalancer": "",//负载均衡
    33           "RateLimitOptions": {//限流
    34               "ClientWhitelist": [],
    35               "EnableRateLimiting": false,
    36               "Period": "",
    37               "PeriodTimespan": 0,
    38               "Limit": 0
    39           },
    40           "AuthenticationOptions": {//认证授权
    41               "AuthenticationProviderKey": "",
    42               "AllowedScopes": []
    43           },
    44           "HttpHandlerOptions": {
    45               "AllowAutoRedirect": true,
    46               "UseCookieContainer": true,
    47               "UseTracing": true,
    48               "MaxConnectionsPerServer": 100
    49           },
    50           "DangerousAcceptAnyServerCertificateValidator": false
    51       }
    • DownstreamPathTemplate:下游路径匹配模板
    • UptreamPathTemplate:上游路径匹配模板即客户端访问地址匹配路径
    • Aggregates: 服务聚合配置
    •  LoadBalancer:负载均衡配置
    • AuthenticationOptions :服务认证、授权
    • RateLimitOptions:限流
    • FileCacheOptions 缓存配置
    • QosOptions:熔断处理

    三.集成网关

      1.新建netcore项目命名OcelorApiGetway,在nuget中搜索并安装Ocelot;

      2.新建json配置文件,命名configuration.json,右键属性“始终复制”,配置文件基本信息如下:

     1 /*基础配置*/
     2 {
     3   "GlobalConfiguration": {
     4 
     5   },
     6   "ReRoutes": [
     7     {
     8       "DownstreamPathTemplate": "/api/values",
     9       "DownstreamScheme": "http",
    10       "DownstreamHostAndPorts": [
    11         {
    12           "Host": "localhost",
    13           "Port": 5001
    14         },
    15         {
    16           "Host": "localhost",
    17           "Port": 5002
    18         }
    19       ],
    20       "UpstreamPathTemplate": "/api/values",
    21       "UpstreamHttpMethod": [ "Get"],
    22       "LoadBalancerOptions": {//负载均衡选项
    23                 "Type": "RoundRobin"//轮询访问
    24               }
    25       }
    26 
    27   ]
    28 }

      3.修改Starup文件,注册服务与管道配置: 

     1      public void ConfigureServices(IServiceCollection services)
     2         {
     3             services.AddOcelot(new ConfigurationBuilder().AddJsonFile("configuration.json")
     4                 .Build()).AddConsul().AddPolly();
     5             services.AddControllers();
     6         }
     7 
     8         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
     9         public  void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    10         {
    11             if (env.IsDevelopment())
    12             {
    13                 app.UseDeveloperExceptionPage();
    14             }
    15 
    16             app.UseHttpsRedirection();
    17             app.UseOcelot();
    18             app.UseRouting();
    19             app.UseEndpoints(endpoints =>
    20             {
    21                 endpoints.MapControllers();
    22             });
    23              
    24         }

      4.新建两个webapi项目,命名为WebApiA,WebApiB,分别新建ValuesController,添加Get方法:

            [HttpGet]
            public IEnumerable<string> Get()
            {
                return new string[] { "This is webApiA" };
            }
            [HttpGet]
            public IEnumerable<string> Get()
            {
                return new string[] { "This is webApiB" };
            }        

    修改两个项目中的launchSettings.json文件中的applicationUrl,分别对应5001,5002;

      5.测试运行:先启动webApiA与WebApiB项目然后运行OcelorApiGetway,如下图:

      

      四.认证和授权

      在 Ocelot API 网关中,可使用提供身份验证令牌的 IdentityServer,在 API 网关外部或内部设置身份验证服务,例如 ASP.NET Core Web API 服务。

    1.新建一项目,命名“WebApiIdentityServer”,添加引用程序:通过NuGet安装 IdentityServer4 或者通过程序包管理执行 Install-Package IdentityServer4 安装依赖包。

    2.新建一个Config类,管理Identity资源,代码如下:

     1 using IdentityServer4.Models;
     2 using System.Collections.Generic;
     3 namespace IdentityClientDemo
     4 {
     5     public static class IdentityClientConfig
     6     {
     7         public static IEnumerable<IdentityResource> GetIdentityResourceResources()
     8         {
     9             return new List<IdentityResource>
    10             {
    11                 new IdentityResources.OpenId(),
    12             };
    13         }
    14         // scopes define the API resources in your system
    15         public static IEnumerable<ApiResource> GetApiResources()
    16         {
    17             //api资源({资源名称}{描述})
    18             return new List<ApiResource>
    19             {
    20                 new ApiResource("Api", "Api"),
    21             };
    22         }
    23 
    24         /// <summary>
    25         /// 添加客户端
    26         /// </summary>
    27         /// <returns></returns>
    28         public static IEnumerable<Client> GetClients()
    29         {
    30             return new List<Client>
    31             {
    32                 new Client
    33                 {
    34                     //客户端id,必须唯一
    35                     ClientId = "client",
    36                     AllowedGrantTypes = GrantTypes.ClientCredentials,//授权方式,这里采用的是客户端认证模式
    37                     ClientSecrets =
    38                     {
    39                         new Secret("secret".Sha256())
    40                     },
    41                     AllowedScopes =
    42                     {
    43                         "Api",
    44                     }
    45                 }
    46             };
    47         }
    48     }
    49 }
    View Code

    3.在startup.class中注入服务:

     1 using Microsoft.AspNetCore.Builder;
     2 using Microsoft.AspNetCore.Hosting;
     3 using Microsoft.Extensions.Configuration;
     4 using Microsoft.Extensions.DependencyInjection;
     5 using Microsoft.Extensions.Hosting;
     6 namespace IdentityClientDemo
     7 {
     8     public class Startup
     9     {
    10         public Startup(IConfiguration configuration)
    11         {
    12             Configuration = configuration;
    13         }
    14 
    15         public IConfiguration Configuration { get; }
    16 
    17         // This method gets called by the runtime. Use this method to add services to the container.
    18         public void ConfigureServices(IServiceCollection services)
    19         {
    20 
    21             services.AddIdentityServer()
    22                  .AddDeveloperSigningCredential()
    23                 .AddInMemoryApiResources(IdentityClientConfig.GetApiResources())//Api资源信息
    24                 .AddInMemoryClients(IdentityClientConfig.GetClients());//客户端信息
    25             services.AddControllers();
    26         }
    27 
    28         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    29         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    30         {
    31             if (env.IsDevelopment())
    32             {
    33                 app.UseDeveloperExceptionPage();
    34             }
    35 
    36             app.UseHttpsRedirection();
    37 
    38             app.UseRouting();
    39 
    40             app.UseAuthorization();
    41             app.UseIdentityServer();
    42             app.UseEndpoints(endpoints =>
    43             {
    44                 endpoints.MapControllers();
    45             });
    46         }
    47     }
    48 }
    View Code

    4.修改launchSetting.json文件,设置applicationUrl的端口为5003:

     1 {
     2   "$schema": "http://json.schemastore.org/launchsettings.json",
     3   "iisSettings": {
     4     "windowsAuthentication": false,
     5     "anonymousAuthentication": true,
     6     "iisExpress": {
     7       "applicationUrl": "http://localhost:5003",
     8       "sslPort": 0
     9     }
    10   },
    11   "profiles": {
    12     "IIS Express": {
    13       "commandName": "IISExpress",
    14       "launchBrowser": true,
    15       "launchUrl": "api/Token",
    16       "environmentVariables": {
    17         "ASPNETCORE_ENVIRONMENT": "Development"
    18       }
    19     },
    20     "WebApiIdentityServer": {
    21       "commandName": "Project",
    22       "launchBrowser": true,
    23       "launchUrl": "api/Token",
    24       "applicationUrl": "https://localhost:5003;http://localhost:5003",
    25       "environmentVariables": {
    26         "ASPNETCORE_ENVIRONMENT": "Development"
    27       }
    28     }
    29   }
    30 }
    View Code

    5.修改OcelotApiGetway项目中的Startup文件,添加身份认证:

     1   public class Startup
     2     {
     3         public Startup(IConfiguration configuration)
     4         {
     5             Configuration = configuration;
     6         }
     7 
     8         public IConfiguration Configuration { get; }
     9 
    10         // This method gets called by the runtime. Use this method to add services to the container.
    11         public void ConfigureServices(IServiceCollection services)
    12         {
    13 
    14             services.AddOcelot(new ConfigurationBuilder().AddJsonFile("configuration.json")
    15                 .Build()).AddConsul().AddPolly();
    16 
    17             services
    18              .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    19              .AddIdentityServerAuthentication("Bearer", options =>
    20              {
    21                  options.Authority = "http://localhost:5003";
    22                  options.RequireHttpsMetadata = false;
    23                  options.ApiName = "api1";
    24                  options.ApiSecret = "secret";
    25              });
    26 
    27             services.AddControllers();
    28         }
    29 
    30         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    31         public  void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    32         {
    33             if (env.IsDevelopment())
    34             {
    35                 app.UseDeveloperExceptionPage();
    36             }
    37 
    38             app.UseHttpsRedirection();
    39             app.UseOcelot();
    40             app.UseRouting();
    41 
    42             app.UseAuthentication();
    43             app.UseAuthorization();
    44 
    45             //app.UseMvc();
    46             app.UseEndpoints(endpoints =>
    47             {
    48                 endpoints.MapControllers();
    49             });
    50              
    51         }
    52     }

    然后修改OcelotApiGetway中Ocelot配置文件,添加认证授权节点:

          //认证授权
          "AuthenticationOptions": {
            "AuthenticationProviderKey": "Bearer",//需要和startup文件中的authenticationScheme 保持一致
            "AllowedScopes": []
          },

    完整配置如下:

     1 /* 认证授权*/
     2 {
     3   "GlobalConfiguration": {
     4     //  "ServiceDiscoveryProvider": {
     5     //    "Host": "localhost",
     6     //    "Port": 8500,
     7     //    "Type": "Consul"
     8     //  }
     9 
    10     "RateLimitOptions": {
    11       "DisableRateLimitHeaders": true,
    12       "QuotaExceededMessage": "Stop request plz!",
    13       "HttpStatusCode": 666,
    14       "ClientIdHeader": "cid"
    15     }
    16 
    17   },
    18   "ReRoutes": [
    19     {
    20       "DownstreamPathTemplate": "/{url}",
    21       "DownstreamScheme": "http",
    22       "DownstreamHostAndPorts": [
    23         {
    24           "Host": "localhost",
    25           "Port": 5001
    26         },
    27         {
    28           "Host": "localhost",
    29           "Port": 5002
    30         },
    31         {
    32           "Host": "localhost",
    33           "Port": 5003
    34         }
    35       ],
    36       //认证授权
    37       "AuthenticationOptions": {
    38         "AuthenticationProviderKey": "Bearer",
    39         "AllowedScopes": []
    40       },
    41       "UpstreamPathTemplate": "/Service1/{url}",
    42       "UpstreamHttpMethod": [ "Get", "Post" ],
    43       //限流
    44       "RateLimitOptions": {
    45         //"ClientWhitelist": [],
    46         "EnableRateLimiting": true, //Boolean值,是否启用限流,只有为true时,配置生效。
    47         "Period": "1m", //限流控制的时间段,可以输入 1s(1秒),1m(1分),1h(1小时),1d(1天)
    48         "PeriodTimespan": 30, //多少秒之后客户端可以重试
    49         "Limit": 200 //在Period时间内最大能访问的数量。
    50       },
    51       //1分钟之内该api最多被访问2次,如果已经达到2次,从第2次请求结束起30秒后才能进行下一次访问。
    52       "LoadBalancerOptions": {
    53         "Type": "RoundRobin"
    54       },
    55       //熔断
    56       "QoSOptions": {
    57         "ExceptionsAllowedBeforeBreaking": 1, //ExceptionsAllowedBeforeBreaking 允许多少个异常请求
    58         "DurationOfBreak": 5000, //DurationOfBreak 熔断的时间,单位为秒
    59         "TimeoutValue": 3000 //TimeoutValue 如果下游请求的处理时间超过多少则自如将请求设置为超时
    60       }
    61       //3秒算一次超时(TimeoutValue:3000),然后允许的异常请求是2次(ExceptionsAllowedBeforeBreaking:1),如果达到了允许异常请求的上限就触发5秒钟的熔断时间(DurationOfBreak:5000)
    62     },
    63     {
    64       "DownstreamPathTemplate": "/{url}",
    65       "DownstreamScheme": "http",
    66       "DownstreamHostAndPorts": [
    67         {
    68           "Host": "localhost",
    69           "Port": 5003
    70         }
    71       ],
    72       "UpstreamPathTemplate": "/service2/{url}",
    73       "UpstreamHttpMethod": [ "Get", "Post" ],
    74       "AuthenticationOptions": {
    75         "AuthenticationProviderKey": "Bearer",
    76         "AllowedScopes": []
    77       }
    78 
    79     }
    80 
    81   ]
    82 }
    View Code

    6.测试运行,启动三个API项目然后运行OcelotApiGetway,可以发现会报401 Unauthorized异常:

     然后调用WebApiIdentityServer项目中的获取token方法,并携带token再次访问:

     

    可以看到能正常请求到数据;

  • 相关阅读:
    js中this的用法
    js原型链与继承(初体验)
    关于C语言指针中的p++与p+i
    react todolist
    react表单提交
    react条件渲染
    react初体验
    初次接触express
    阿里内推在线编程题(返回元素的选择器)
    模块初始化
  • 原文地址:https://www.cnblogs.com/SecondSun/p/14419710.html
Copyright © 2020-2023  润新知