Ocelot简易教程(五)之集成IdentityServer认证以及受权

Ocelot简易教程目录

  1. Ocelot简易教程(一)之Ocelot是什么
  2. Ocelot简易教程(二)之快速开始1
  3. Ocelot简易教程(二)之快速开始2
  4. Ocelot简易教程(三)之主要特性及路由详解
  5. Ocelot简易教程(四)之请求聚合以及服务发现
  6. Ocelot简易教程(五)之集成IdentityServer认证以及受权
  7. Ocelot简易教程(六)之重写配置文件存储方式并优化响应数据
  8. Ocelot简易教程(七)之配置文件数据库存储插件源码解析html

    做者:依乐祝
    原文地址:http://www.javashuo.com/article/p-bycbsvjo-x.htmlgit

最近比较懒,因此隔了N天才来继续更新第五篇Ocelot简易教程,本篇教程会先简单介绍下官方文档记录的内容而后在前几篇文档代码的基础上进行实例的演示。目的是为了让小白也能按照步骤把代码跑起来。固然,在开始以前你要对IdentityServer有必定的了解,而且可以进行IdentityServer的集成,若是你还不会集成IdentityServer的话仍是先看看个人这篇Asp.NetCoreWebApi图片上传接口(二)集成IdentityServer4受权访问(附源码)文章吧。里面有一步一步的集成IdentityServer的实例。github

好了,废话说完了,那就让咱们开始进入今天的主题吧!Ocelot认证与受权。web

概念表述

认证

为了验证ReRoutes并随后使用Ocelot的任何基于声明的功能,例如受权或使用令牌中的值修改请求。 用户必须像往常同样在他们的Startup.cs中注册认证服务,唯一的不一样是他们须要给每一个认证注册提供一个方案,例如数据库

public void ConfigureServices(IServiceCollection services)
{
    var authenticationProviderKey = "OcelotKey";

    services.AddAuthentication()
        .AddJwtBearer(authenticationProviderKey, x =>
        {
        });
}

在此示例中,OcelotKey是此提供程序已注册的方案。而后咱们将其映射到配置中的ReRoute,例如json

"ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 1001
        },
        {
          "Host": "localhost",
          "Port": 1002
        }
      ],
      "UpstreamPathTemplate": "/{everything}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "OcelotKey",
        "AllowedScopes": []
      }
    }
  ]

当Ocelot运行时,它将查看此ReRoutes中 AuthenticationOptions节点下面的AuthenticationProviderKey并检查是否有使用给定密钥注册的身份验证提供程序。若是没有,那么Ocelot不会启动,若是有的话ReRoute将在执行时使用该提供者。c#

若是对ReRoute进行了身份验证,则Ocelot将在执行身份验证中间件时调用与其关联的认证方案。若是请求失败,则认证Ocelot返回http的状态代码为401即未受权状态。api

JWT令牌

若是您想使用JWT令牌进行身份验证,可能来自OAuth之类的提供程序,您能够正常注册您的身份验证中间件,例如缓存

public void ConfigureServices(IServiceCollection services)
{
    var authenticationProviderKey = "OcelotKey";

    services.AddAuthentication()
        .AddJwtBearer(authenticationProviderKey, x =>
        {
            x.Authority = "test";
            x.Audience = "test";
        });

    services.AddOcelot();
}

而后将身份验证提供程序密钥映射到配置中的ReRoute,例如服务器

"ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 1001
        },
        {
          "Host": "localhost",
          "Port": 1002
        }
      ],
      "UpstreamPathTemplate": "/{everything}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "OcelotKey",
        "AllowedScopes": []
      }
    }
  ]

Identity Server Bearer Tokens认证

接下来上今天的主角了。identityServer认证方式。为了使用IdentityServer承载令牌,请按照惯例在ConfigureServices 中使用方案(密钥)注册您的IdentityServer服务。 若是您不明白如何操做,请访问IdentityServer文档。或者查看个人这篇Asp.NetCoreWebApi图片上传接口(二)集成IdentityServer4受权访问(附源码)文章。

var authenticationProviderKey = "OcelotKey";
            var identityServerOptions = new IdentityServerOptions();
            Configuration.Bind("IdentityServerOptions", identityServerOptions);
            services.AddAuthentication(identityServerOptions.IdentityScheme)
                .AddIdentityServerAuthentication(authenticationProviderKey, options =>
                {
                    options.RequireHttpsMetadata = false; //是否启用https
                    options.Authority = $"http://{identityServerOptions.ServerIP}:{identityServerOptions.ServerPort}";//配置受权认证的地址
                    options.ApiName = identityServerOptions.ResourceName; //资源名称,跟认证服务中注册的资源列表名称中的apiResource一致
                    options.SupportedTokens = SupportedTokens.Both;
                }
                );
            services.AddOcelot()//注入Ocelot服务
                    .AddConsul();

而后将身份验证提供程序密钥映射到配置中的ReRoute,例如

"ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 1001
        },
        {
          "Host": "localhost",
          "Port": 1002
        }
      ],
      "UpstreamPathTemplate": "/{everything}",
      "UpstreamHttpMethod": [ "Get", "Post" ],
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "OcelotKey",
        "AllowedScopes": []
      }
    }
  ]

容许访问的范围(Allowed Scopes)

若是将范围添加到AllowedScopes,Ocelot将得到类型范围的全部用户声明(从令牌中),并确保用户具备列表中的全部范围。

这是一种基于范围限制对ReRoute访问的方式。(我也没用过这种方式,感受有点相似IdentityServer Scope的概念)

实例演示集成IdentityServer

  1. 新建一个OcelotDemo.Auth asp.net core web api项目

  2. 项目进行IdentityServer服务端相关的配置,这里为了演示的方便采用硬编码的方式进行的配置。具体配置能够参考Asp.NetCoreWebApi图片上传接口(二)集成IdentityServer4受权访问(附源码)这篇文章

  3. 在网关项目OcelotDemo中添加Nuget包

    Install-Package IdentityServer4.AccessTokenValidation
  4. 在OcelotDemo项目中的Startup.cs中加入identityServer验证,以下所示:

    var authenticationProviderKey = "OcelotKey";
                var identityServerOptions = new IdentityServerOptions();
                Configuration.Bind("IdentityServerOptions", identityServerOptions);
                services.AddAuthentication(identityServerOptions.IdentityScheme)
                    .AddIdentityServerAuthentication(authenticationProviderKey, options =>
                    {
                        options.RequireHttpsMetadata = false; //是否启用https
                        options.Authority = $"http://{identityServerOptions.ServerIP}:{identityServerOptions.ServerPort}";//配置受权认证的地址
                        options.ApiName = identityServerOptions.ResourceName; //资源名称,跟认证服务中注册的资源列表名称中的apiResource一致
                        options.SupportedTokens = SupportedTokens.Both;
                    }
                    );
                services.AddOcelot()//注入Ocelot服务
                        .AddConsul();
  5. 在ocelot.json中须要加入验证的ReRoute中,修改成以下的配置代码:

    "ReRoutes": [
        {
          "DownstreamPathTemplate": "/api/{everything}",
          "DownstreamScheme": "http",
          "DownstreamHostAndPorts": [
            {
              "Host": "localhost",
              "Port": 1001
            },
            {
              "Host": "localhost",
              "Port": 1002
            }
          ],
          "UpstreamPathTemplate": "/{everything}",
          "UpstreamHttpMethod": [ "Get", "Post" ],
          "LoadBalancerOptions": {
            "Type": "RoundRobin"
          },
          "AuthenticationOptions": {
            "AuthenticationProviderKey": "OcelotKey",
            "AllowedScopes": []
          }
        }
      ]
  6. 打开PostMan测试一下代码吧,首先访问一下http://localhost:1000/values 这时候返回的结果是401未受权的状态,以下图所示:

    1539780575952

  7. 而后访问咱们上面新建的IdentityServer服务器并获取Token。以下图所示配置对应的参数进行获取:

    1539780272769

  8. 而后使用咱们获取到的access_token进行Ocelot网关接口的访问,以下所示进行配置:

    1539780805247

    能够看到结果返回了200代码,而且结果在Good以及Order之间进行切换。由于Ocelot.json文件中对路由进行了RoundRobin的负载均衡的策略。

受权

Ocelot支持基于声明的受权,该受权在身份验证后运行。这意味着若是您有要受权的Url,则能够将如下内容添加到ReRoute配置中。

"RouteClaimsRequirement": {
    "UserType": "registered"
}

在此示例中,当调用受权中间件时,Ocelot将检查用户是否具备声明类型UserType以及是否已注册该声明的值。若是不是,则用户将不被受权,而且将响应403禁止访问的状态码。

固然这种受权的方式在大部分业务场景中都是不适用的,须要本身重写Ocelot的中间件才能实现。经过Ocelot中间件的重写你能够实现本身的受权逻辑,若是你还有限流的需求,好比说对每一个客户端进行不一样的限流策略。比方说,有三个客户端A,B,C。访问相同的URL,可是咱们要控制A,每分钟只能访问10次,B每分钟能访问20次,而C不容许访问。针对这个场景Ocelot却没有相关的实现。可是咱们能够经过重写Ocelot中间件来实现它。因为篇幅有限,因此今天就不进行介绍了。可是我会抽时间进行相关的实现,并分享给你们。

源码

本篇博文的源码已经上传到Github。能够进行参考。https://github.com/yilezhu/OcelotDemo

总结

本文先大体介绍一下Ocelot如何集成认证受权,而后经过实例进行了IdentityServer集成的演示,但愿能对你们有必定的参考做用。固然文中也提到了,应对复杂的受权以及限流须要自行重写Ocelot中间件进行实现。具体如何实现呢,我会尽快分享给你们。一样的经过重写Ocelot中间件咱们还能够把ocelot.json的配置信息存储到数据库并缓存到Redis中!最后,感谢你们的阅读!

相关文章
相关标签/搜索