6

微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用

 2 years ago
source link: https://www.cnblogs.com/wei325/p/15415766.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.



Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现

Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocelot+Consul

Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Ocelot+Polly缓存、限流、熔断、降级

微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用

 描述:微服务网关中,需要对访问的接口进行身份校验后再转发请求,网关中鉴权的方式有很多种,这里介绍的是常用的IdentityServer4鉴权添加到Ocelot网关中,同时下游的服务也要做身份校验,

      防止请求绕过网关直接请求下游服务。

二、创建IdentityServer4项目

这里重点不是说IdentityServer4,所以这里建一个简单的示例项目。

1.创建一个Identity4.Api项目

引入NugGet包

IdentityServer4
IdentityServer4.Storage

这里用的都是4.1.2版本

2.在项目中创建一个config静态类

 /// <summary>
    /// 配置
    /// </summary>
    public class Config
    {
        /// <summary>
        /// 定义作用域
        /// </summary>
        public static IEnumerable<ApiScope> ApiScopes =>
            new ApiScope[]
            {
            new ApiScope("gatewayScope"),
            new ApiScope("scope2")
            };

        public static IEnumerable<ApiResource> ApiResources =>
            new ApiResource[]
            {

                new ApiResource("server1","服务1")
                {
                    //4.x必须写
                    Scopes = { "gatewayScope" }
                },
            };

        public static IEnumerable<Client> Clients =>
            new Client[]
            {
            new Client
            {
                ClientId = "client_test",
                ClientName = "测试客户端",

                AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                ClientSecrets = { new Secret("secret_test".Sha256()) },

                AllowedScopes = { "gatewayScope" }
            },
            };

        /// <summary>
        /// 测试的账号和密码
        /// </summary>
        /// <returns></returns>
        public static List<TestUser> GetTestUsers()
        {
            return new List<TestUser>
    {
        new TestUser()
        {
             SubjectId = "1",
             Username = "test",
             Password = "123456"
        }
    };
        }
    }

 3.在Startup.cs的ConfigureServices()方法中加入

 public void ConfigureServices(IServiceCollection services)
        {
            #region 内存方式
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryApiResources(Config.ApiResources)
                .AddInMemoryClients(Config.Clients)
                .AddInMemoryApiScopes(Config.ApiScopes) //4.x新加
                .AddTestUsers(Config.GetTestUsers());
            #endregion
            services.AddControllersWithViews();
        }

4.在Startup.cs的Configure()方法中加入

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseIdentityServer();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

到这里一个IdentitySever4的鉴权中心就建好了,运行起来,用Postman测试获取token。

 token获取成功,说明IdentityServer4的鉴权中心没问题了。

三、Ocelot中加入IdentityServer4认证

Ocelot网关默认已经集成了Id4的,我们需要做的事情有:

1.在配置中加入IdentityServer4的信息,ocelog.json中加入

{
    "Routes": [
      {
        //转发到下游服务地址--url变量
        "DownstreamPathTemplate": "/api/{url}",
        //下游http协议
        "DownstreamScheme": "http",
        //负载方式,
        "LoadBalancerOptions": {
          "Type": "RoundRobin" // 轮询
        },
        //上游地址
        "UpstreamPathTemplate": "/T1/{url}", //网关地址--url变量   //冲突的还可以加权重Priority
        "UpstreamHttpMethod": [ "GET", "POST", "DELETE", "PUT" ],
        "UseServiceDisConvery": true, //使用服务发现
        "ServiceName": "api", //Consul服务名称
        //熔断设置,熔断器使用Polly
        "QoSOptions": {
          "ExceptionsAllowedBeforeBreaking": 3, //允许多少个异常请求
          "DurationOfBreak": 10000, // 熔断的时间10s,单位为ms
          "TimeoutValue": 5000 //单位ms,如果下游请求的处理时间超过多少则自动将请求设置为超时 默认90秒
        },
        //鉴权
        "AuthenticationOptions": {
          "AuthenticationProviderKey": "Bearer", //指定一个key
          "AllowedScopes": [ "gatewayScope" ] //id4的作用域名称
        }
      }
    ],
    "GlobalConfiguration": {
      //Ocelot应用对外地址
      "BaseUrl": "http://172.16.2.9:5200",
      "ServiceDiscoveryProvider": {
        //Consul地址
        "Host": "172.16.2.84",
        //Consul端口
        "Port": 8500,
        "Type": "Consul" //由Consul提供服务发现,每次请求Consul
      }
    }
  }

2.把Id4加入到IOC中

添加NuGet包

IdentityServer4.AccessTokenValidation

Ocelot项目Startup.cs中的ConfigureServices()方法加上

public void ConfigureServices(IServiceCollection services)
{
var authenticationProviderKey = "Bearer"; //这个为上面配置里的key
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(authenticationProviderKey, options =>
{
options.Authority = "http://localhost:5000";//id4服务地址
options.ApiName = "server1";//id4 api资源里的apiname
options.RequireHttpsMetadata = false; //不使用https
options.SupportedTokens = SupportedTokens.Both;
});
services.AddOcelot()
.AddConsul()
.AddPolly();
}

到这里,Ocelot网关配置Id4就配好了。

3.测试验证

先测试加了Id4后,不带token访问下网关

 可以看到,报了401,没权限访问,再试一下把上面id4取到的token带上访问。

 发现可以访问成功了。这Ocelot中加入Id4校验就完成了。

四、下游服务加入IdentityServer4认证

为什么下游服务要加身份校验呢,因为请求可能绕过网关直接访问下游服务,没有验证就会出问题了。

只需要在startup.cs中的ConfigureServices中加入上面的代码,去掉AuthenticationProviderKey

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";//id4服务地址
options.ApiName = "server1";//id4 api资源里的apiname
options.RequireHttpsMetadata = false; //不使用https
options.SupportedTokens = SupportedTokens.Both;
});
services.AddControllers().AddJsonOptions(cfg =>
{
cfg.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
});
services.AddSingleton<OrderService>();
}

然后在Configure()方法中,    app.UseRouting();后面加上  app.UseAuthentication();

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
            //Consul注册
            app.UseConsul(Configuration);
        }

然后在要校验的地方加上[Authorize]

2.校验不带token直接访问下游服务

 显示没权限,再试带上token直接访问下游服务。

 很好,成功访问,然后再试下通过网关访问是否能正常访问。

也成了,全部配置完成!

源码地址:https://github.com/weixiaolong325/Ocelot-Consul-Polly-Id4.Demo


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK