如何检查数组中的声明值或 Ocelot 网关中的任何值?

Posted

技术标签:

【中文标题】如何检查数组中的声明值或 Ocelot 网关中的任何值?【英文标题】:How to check Claim value in array or any in Ocelot gateway? 【发布时间】:2020-06-03 14:56:28 【问题描述】:

假设我有 2 个这样的端点

    订单创建:要求声明 order_perm 具有数组 ["order_create", "order_edit"] 中的值 订单搜索:只需要声明 order_perm 存在

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

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

但是当应用程序启动时它会崩溃,在第 2 种情况下。我是这样设置的

"RouteClaimsRequirement": 
            "order_perm": ""
          

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

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

【问题讨论】:

【参考方案1】:

我知道这是一个老问题,我最近被困在同一件事上,经过大量谷歌搜索后,我在 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;
        
    

【讨论】:

以上是关于如何检查数组中的声明值或 Ocelot 网关中的任何值?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查数组字段是不是包含唯一值或 MongoDB 中的另一个数组?

Ocelot Api网关教程- QoS

在 Ocelot API 网关中间件中返回未授权

Ocelot一款.NET下的API网关介绍

[置顶] 基于.NET平台的Ocelot网关框架教程汇总

如何在 .net api 网关中使用 gRPC 服务?