.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,希望对大家有参考价值。如果文中有错误请联系我更改。

posted @   MaxBruce  阅读(361)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
历史上的今天:
2021-05-19 堆排序——Java实现
点击右上角即可分享
微信分享提示