• .Net Core使用Ocelot网关(二) 鉴权认证


    引用网址:https://blog.csdn.net/zhanglong_longlong/article/details/120011444

    前言

    上一章已经简单的介绍了ocelot的使用了,但是网关暴露的接口如果什么人都能访问的话安全性就太低啦。所以我们需要去鉴权和认证。这里我们使用identityServer4给我们的网关来鉴权认证。

    创建Identity服务

    我们创建一个identity的服务来用于令牌的发放和鉴权。下图是我的项目结构。
     

    20191216163523.png


    Api_Gatewat端口:5000
    Api_A端口:5001
    Api_B端口:5002
    IdentityServer端口:5003

    通过nuget添加IdentityServer4的包,也可以通过程序包管理控制台执行以下命令Install-Package IdentityServer4

    添加一个Congif文件。

    1.  
      using System.Collections.Generic;
    2.  
      using IdentityModel;
    3.  
      using IdentityServer4;
    4.  
      using IdentityServer4.Models;
    5.  
       
    6.  
      namespace IdentityServer
    7.  
      {
    8.  
      public static class Config
    9.  
      {
    10.  
      public static IEnumerable<IdentityResource> GetIdentityResourceResources()
    11.  
      {
    12.  
      return new List<IdentityResource>
    13.  
      {
    14.  
      new IdentityResources.OpenId(), //必须要添加,否则报无效的scope错误
    15.  
      };
    16.  
      }
    17.  
      // scopes define the API resources in your system
    18.  
      public static IEnumerable<ApiResource> GetApiResources()
    19.  
      {
    20.  
      //可访问的API资源(资源名,资源描述)
    21.  
      return new List<ApiResource>
    22.  
      {
    23.  
      new ApiResource("Api_A", "Api_A"),
    24.  
      new ApiResource("Api_B", "Api_B")
    25.  
      };
    26.  
      }
    27.  
       
    28.  
      public static IEnumerable<Client> GetClients()
    29.  
      {
    30.  
      return new List<Client>
    31.  
      {
    32.  
      new Client
    33.  
      {
    34.  
      ClientId = "client_a", //访问客户端Id,必须唯一
    35.  
      //使用客户端授权模式,客户端只需要clientid和secrets就可以访问对应的api资源。
    36.  
      AllowedGrantTypes = GrantTypes.ClientCredentials,
    37.  
      ClientSecrets =
    38.  
      {
    39.  
      new Secret("secret".Sha256())
    40.  
      },
    41.  
      AllowedScopes = { "Api_A",IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile }
    42.  
      },
    43.  
      new Client
    44.  
      {
    45.  
      ClientId = "client_b",
    46.  
      ClientSecrets = new [] { new Secret("secret".Sha256()) },
    47.  
      AllowedGrantTypes = GrantTypes.ClientCredentials,
    48.  
      AllowedScopes = { "Api_B",IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile }
    49.  
      }
    50.  
      };
    51.  
      }
    52.  
      }
    53.  
      }

    添加两个API资源,并且添加两个客户端分别去访问不同资源。

    在 Startup 中的 ConfigureServices 中配置IdentityServer服务。

    1.  
      public void ConfigureServices(IServiceCollection services)
    2.  
      {
    3.  
      services.AddIdentityServer()
    4.  
      .AddDeveloperSigningCredential()
    5.  
      .AddInMemoryApiResources(Config.GetApiResources())
    6.  
      .AddInMemoryClients(Config.GetClients());
    7.  
      }

    在 Configure 中把IdentityServer放入http管道中。

    1.  
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    2.  
      {
    3.  
      if (env.IsDevelopment())
    4.  
      {
    5.  
      app.UseDeveloperExceptionPage();
    6.  
      }
    7.  
      app.UseIdentityServer();
    8.  
      }

    为ocelot集成Identity

    通过nuget添加IdentityServer4.AccessTokenValidation的包,也可以通过程序包管理控制台执行以下命令 Install-Package IdentityServer4.AccessTokenValidation

    IdentityServer4.AccessTokenValidation - 用于验证IdentityServer4中的JWT和引用令牌

    在 Startup 的 ConfigureServices 中分别注册两个认证方案 Configure 中配置IdentityServer服务。

    1.  
      public void ConfigureServices(IServiceCollection services)
    2.  
      {
    3.  
       
    4.  
      services.AddAuthentication()
    5.  
      .AddJwtBearer("Api_A", i =>
    6.  
      {
    7.  
      i.Audience = "Api_A";
    8.  
      i.Authority = "http://localhost:5003";
    9.  
      i.RequireHttpsMetadata = false;
    10.  
      }).AddJwtBearer("Api_B", y =>
    11.  
      {
    12.  
      y.Audience = "Api_B";
    13.  
      y.Authority = "http://localhost:5003";
    14.  
      y.RequireHttpsMetadata = false;
    15.  
      });
    16.  
      services.AddOcelot(new ConfigurationBuilder()
    17.  
      .AddJsonFile("configuration.json")
    18.  
      .Build());
    19.  
      }
    20.  
       
    21.  
      public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    22.  
      {
    23.  
      if (env.IsDevelopment())
    24.  
      {
    25.  
      app.UseDeveloperExceptionPage();
    26.  
      }
    27.  
      app.UseOcelot();
    28.  
      app.UseAuthorization();
    29.  
      }

    并修改ocelot配置文件,在Routes中添加授权信息

    1.  
      {
    2.  
      "ReRoutes": [
    3.  
      {
    4.  
      "UpstreamPathTemplate": "/Api_A/{controller}/{action}",
    5.  
      "DownstreamPathTemplate": "/api/{controller}/{action}",
    6.  
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
    7.  
      "DownstreamScheme": "http",
    8.  
      "DownstreamHostAndPorts": [
    9.  
      {
    10.  
      "Host": "localhost",
    11.  
      "Port": 5001
    12.  
      }
    13.  
       
    14.  
      ],
    15.  
      "RateLimitOptions": {
    16.  
      "ClientWhitelist": [ "127.0.0.1" ],
    17.  
      "EnableRateLimiting": true,
    18.  
      "Period": "1m",
    19.  
      "PeriodTimespan": 30,
    20.  
      "Limit": 5
    21.  
      },
    22.  
      "FileCacheOptions": {
    23.  
      "TtlSeconds": 5,
    24.  
      "Region": "time"
    25.  
      },
    26.  
      "UpstreamHeaderTransform": {
    27.  
      "demo": "a,b"
    28.  
      },
    29.  
      "DownstreamHeaderTransform": {
    30.  
      "demo": "xxxxxxx",
    31.  
      "Location": "{DownstreamBaseUrl},{BaseUrl}"
    32.  
      },
    33.  
      //授权信息
    34.  
      "AuthenticationOptions": {
    35.  
      "AuthenticationProviderKey": "Api_A",
    36.  
      "AllowedScopes": []
    37.  
      }
    38.  
      },
    39.  
      {
    40.  
      "UpstreamPathTemplate": "/Api_B/{controller}/{action}",
    41.  
      "DownstreamPathTemplate": "/api/{controller}/{action}",
    42.  
      "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
    43.  
      "DownstreamScheme": "http",
    44.  
      "DownstreamHostAndPorts": [
    45.  
      {
    46.  
      "Host": "localhost",
    47.  
      "Port": 5002
    48.  
      }
    49.  
       
    50.  
      ],
    51.  
      //授权信息
    52.  
      "AuthenticationOptions": {
    53.  
      "AuthenticationProviderKey": "Api_B",
    54.  
      "AllowedScopes": []
    55.  
      }
    56.  
      }
    57.  
      ],
    58.  
      "QoSOptions": {
    59.  
      "ExceptionsAllowedBeforeBreaking": 3,
    60.  
      "DurationOfBreak": 20,
    61.  
      "TimeoutValue": 5000
    62.  
      },
    63.  
      "GlobalConfiguration": {
    64.  
      "RateLimitOptions": {
    65.  
      "DisableRateLimitHeaders": false,
    66.  
      "QuotaExceededMessage": "接口限流!",
    67.  
      "HttpStatusCode": 200,
    68.  
      "ClientIdHeader": "ClientId"
    69.  
      }
    70.  
      }
    71.  
      }

    Ocelot会去检查ReRoutes是否配置了AuthenticationOptions节点。如果有会根据配置的认证方案进行身份认证。如果没有则不进行身份认证。
    AuthenticationProviderKey 是刚才注册的认证方案。
    AllowedScopes 是 AllowedScopes中配置的授权访问范围。

    演示效果

    我们为api_a和api_b分别注册了认证方案。如果我们不申请token是会401没有权限访问。

    20191218152014.png

    我们通过identityServer申请一个的token,并用它访问api_a和api_b。
     

    20191218154725.png


     

    20191218160205.png


    QQ20191218-152516-HD (1).gif
    可以看到我们申请的token是可以访问api_a的,但是不能访问api_b,因为client_a这个客户端只有访问api_a的权利。如果想访问api_b使用client_b申请token就可以啦。

    总结

    简单为Ocelot集成了IdentityServer,希望对大家有参考价值。如果文中有错误请联系我更改。

  • 相关阅读:
    React——from
    React——条件渲染
    React——event
    React——组件
    React——JSX
    flask_mail使用
    flask开发restful api
    mysql limit和offset用法
    flask打包安装文件
    flask-sqlalchemy使用及数据迁移
  • 原文地址:https://www.cnblogs.com/bruce1992/p/16290646.html
Copyright © 2020-2023  润新知