zoukankan      html  css  js  c++  java
  • .Net Core使用Ocelot网关(二) -鉴权认证

    前言

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

    创建Identity服务

    我们创建一个identity的服务来用于令牌的发放和鉴权。下图是我的项目结构。
    20191216163523.png
    Api_Gatewat端口:5000
    Api_A端口:5001
    Api_B端口:5002
    IdentityServer端口:5003

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

    添加一个Congif文件。

    using System.Collections.Generic;
    using IdentityModel;
    using IdentityServer4;
    using IdentityServer4.Models;
    
    namespace IdentityServer
    {
        public static class Config
        {
            public static IEnumerable<IdentityResource> GetIdentityResourceResources()
            {
                return new List<IdentityResource>
                {
                    new IdentityResources.OpenId(), //必须要添加,否则报无效的scope错误
                };
            }
            // scopes define the API resources in your system
            public static IEnumerable<ApiResource> GetApiResources()
            {
                //可访问的API资源(资源名,资源描述)
                return new List<ApiResource>
                {
                    new ApiResource("Api_A", "Api_A"),
                    new ApiResource("Api_B", "Api_B")
                };
            }
    
            public static IEnumerable<Client> GetClients()
            { 
                return new List<Client>
                {
                    new Client
                    {
                        ClientId = "client_a", //访问客户端Id,必须唯一
                        //使用客户端授权模式,客户端只需要clientid和secrets就可以访问对应的api资源。
                        AllowedGrantTypes = GrantTypes.ClientCredentials,
                        ClientSecrets =
                        {
                            new Secret("secret".Sha256())
                        },
                        AllowedScopes = { "Api_A",IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile }
                    },
                    new  Client
                    {
                        ClientId = "client_b",
                        ClientSecrets = new [] { new Secret("secret".Sha256()) },
                        AllowedGrantTypes = GrantTypes.ClientCredentials,
                        AllowedScopes = { "Api_B",IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile }
                    }
                };
            }
        }
    }
    

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

    Startup 中的 ConfigureServices 中配置IdentityServer服务。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients());
    }
    

    Configure 中把IdentityServer放入http管道中。

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseIdentityServer();
    }
    

    为ocelot集成Identity

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

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

    StartupConfigureServices 中分别注册两个认证方案 Configure 中配置IdentityServer服务。

    public void ConfigureServices(IServiceCollection services)
    {
    
        services.AddAuthentication()
                .AddJwtBearer("Api_A", i =>
                {
                    i.Audience = "Api_A";
                    i.Authority = "http://localhost:5003";
                    i.RequireHttpsMetadata = false;
                }).AddJwtBearer("Api_B", y =>
                {
                    y.Audience = "Api_B";
                    y.Authority = "http://localhost:5003";
                    y.RequireHttpsMetadata = false;
                });
        services.AddOcelot(new ConfigurationBuilder()
                .AddJsonFile("configuration.json")
                .Build());
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseOcelot();
        app.UseAuthorization();
    }
    

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

    {
      "ReRoutes": [
        {
          "UpstreamPathTemplate": "/Api_A/{controller}/{action}",
          "DownstreamPathTemplate": "/api/{controller}/{action}",
          "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
          "DownstreamScheme": "http",
          "DownstreamHostAndPorts": [
            {
              "Host": "localhost",
              "Port": 5001
            }
    
          ],
          "RateLimitOptions": {
            "ClientWhitelist": [ "127.0.0.1" ],
            "EnableRateLimiting": true,
            "Period": "1m",
            "PeriodTimespan": 30,
            "Limit": 5
          },
          "FileCacheOptions": {
            "TtlSeconds": 5,
            "Region": "time"
          },
          "UpstreamHeaderTransform": {
            "demo": "a,b"
          },
          "DownstreamHeaderTransform": {
            "demo": "xxxxxxx",
            "Location": "{DownstreamBaseUrl},{BaseUrl}"
          },
          //授权信息
          "AuthenticationOptions": {
            "AuthenticationProviderKey": "Api_A",
            "AllowedScopes": []
          }
        },
        {
          "UpstreamPathTemplate": "/Api_B/{controller}/{action}",
          "DownstreamPathTemplate": "/api/{controller}/{action}",
          "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
          "DownstreamScheme": "http",
          "DownstreamHostAndPorts": [
            {
              "Host": "localhost",  
              "Port": 5002
            }
    
          ],
          //授权信息
          "AuthenticationOptions": {
            "AuthenticationProviderKey": "Api_B",
            "AllowedScopes": []
          }
        }
      ],
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3,
        "DurationOfBreak": 20,
        "TimeoutValue": 5000
      },
      "GlobalConfiguration": {
        "RateLimitOptions": {
          "DisableRateLimitHeaders": false,
          "QuotaExceededMessage": "接口限流!",
          "HttpStatusCode": 200,
          "ClientIdHeader": "ClientId"
        }
      }
    }
    

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

  • 相关阅读:
    fn project 试用之后的几个问题的解答
    fn project 扩展
    fn project 生产环境使用
    fn project 对象模型
    fn project AWS Lambda 格式 functions
    fn project 打包Function
    fn project Function files 说明
    fn project hot functions 说明
    fn project k8s 集成
    fn project 私有镜像发布
  • 原文地址:https://www.cnblogs.com/linhuiy/p/12060277.html
Copyright © 2011-2022 走看看