3

假设我有 2 个这样的端点

  1. 订单创建:需要使用数组["order_create", "order_edit"]中的值声明order_perm
  2. 订单搜索:只需要声明order_perm存在

在案例 1. 中,我将上面的数组传递给RouteClaimsRequirement,如下所示

"RouteClaimsRequirement": {
        "order_perm": ["order_create", "order_edit"]
      }

但是当应用程序启动时它会崩溃,如果是 2。我这样设置

"RouteClaimsRequirement": {
            "order_perm": ""
          }

但用户声称“order_perm”:“create_order”授权失败。

RouteClaimsRequirement是否支持这些用例?如果是这样,我该怎么做?

4

1 回答 1

4

我知道这是一个老问题,我最近被困在同一件事上,经过大量谷歌搜索后,我在github上找到了这个解决方案。当我使用 Ocelot 16.0.1 时,我更改了一些内容以使其对我有用。ocelot.json 文件

{
  "DownstreamPathTemplate": "/api/{everything}/{everything}",
  "DownstreamScheme": "http",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost",
      "Port": "80"
    }
  ],
  "UpstreamPathTemplate": "/web/{everything}/{everything}",
  "UpstreamHttpMethod": [ "GET" ],
  "AuthenticationOptions": {
    "AuthenticationProviderKey": "Authkey",
    "AllowedScopes": []
  },
  "RouteClaimsRequirement": {
    "Role": "Admin , SuperAdmin"
  },
  "SwaggerKey": "myapi"

},

配置方法

public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        //your code here
        var configration = new OcelotPipelineConfiguration
        {
            AuthorisationMiddleware=async (ctx, next) =>
            {
                if (this.Authorize(ctx))
                {
                    await next.Invoke();
                }
                else
                {
                    ctx.Items.SetError(new UnauthorisedError($"Fail to authorize"));
                }
            }
        };
        //your code here
        await app.UseOcelot(configration);
    }

授权方式

 private bool Authorize(HttpContext ctx)
    {
        if (ctx.Items.DownstreamRoute().AuthenticationOptions.AuthenticationProviderKey == null) return true;
        else
        {

            bool auth = false;
            Claim[] claims = ctx.User.Claims.ToArray<Claim>();
            Dictionary<string, string> required = ctx.Items.DownstreamRoute().RouteClaimsRequirement;
            Regex reor = new Regex(@"[^,\s+$ ][^\,]*[^,\s+$ ]");
            MatchCollection matches;

            Regex reand = new Regex(@"[^&\s+$ ][^\&]*[^&\s+$ ]");
            MatchCollection matchesand;
            int cont = 0;
            foreach (KeyValuePair<string, string> claim in required)
            {
                matches = reor.Matches(claim.Value);
                foreach (Match match in matches)
                {
                    matchesand = reand.Matches(match.Value);
                    cont = 0;
                    foreach (Match m in matchesand)
                    {
                        foreach (Claim cl in claims)
                        {
                            if (cl.Type == claim.Key)
                            {
                                if (cl.Value == m.Value)
                                {
                                    cont++;
                                }
                            }
                        }
                    }
                    if (cont == matchesand.Count)
                    {
                        auth = true;
                        break;
                    }
                }
            }
            return auth;
        }
    }
于 2020-06-15T14:34:52.093 回答