【问题标题】:Integrate Open Policy Agent with ASP.Net Core web API将 Open Policy Agent 与 ASP.Net Core Web API 集成
【发布时间】:2026-01-04 23:00:02
【问题描述】:

我浏览了一些关于 OPA(开放策略代理)的视频和教程,发现使用它跨多个服务/API 实现身份验证和授权非常酷。但是,我无法获得有关如何在 Windows 上安装它并将其与 ASP.Net 核心 Web API 集成以实现身份验证和授权的任何见解。任何人都可以帮助我吗?

谢谢,

阿米特·阿南德

【问题讨论】:

    标签: open-policy-agent


    【解决方案1】:

    在不了解您的用例或您运行的平台的情况下,这里有一些一般性建议。

    1. 架构。决定是要将 OPA 作为 sidecar 还是作为独立服务运行。这是一个架构问题,取决于延迟、性能和策略所需的数据。 OPA 是一个被设计为 sidecar 的构建块,但您可以通过旋转多个副本、在它们之间进行负载平衡、添加持久层等来围绕 OPA 构建服务。

    2. 管理。决定 how to load/update policies and log decisions 到 OPA,如果适用,决定如何 load data into OPA

    3. 服务集成。如果您使用的网络代理会拦截所有流向您的服务(例如 Envoy、Linkerd、Kong 等)的网络流量,您可以 configure your network proxy to call out to OPA 而不修改您的 .Net 服务。如果您不使用网络代理,请修改您的 .Net 服务以在您的服务需要策略决策时生成 HTTP callouts,并尽可能使用库以尽量减少对单个服务的影响。 integration page 展示了如何使用 Java Spring 和 PHP。

    【讨论】:

      【解决方案2】:

      Tim Hinrichs 上面的回答很中肯。但是,要在此处添加一些特定的解决方案。在以下 2 个解决方案中,我建议使用 REST API 和 ASP.NET 中间件。此外,虽然 OPA 理论上可以用作身份验证工具,但我建议不要这样做。它的目的是授权。

      使用 ASP.NET 授权中间件

      首先,OPA 将作为它自己的服务、作为 k8 中的 sidecar 或在 Docker 容器中运行。 OPA 的文档很好地展示了如何实现它的示例,因此我不会详细说明。

      在这里,您将创建一个查询 OPA's Rest API 的 .NET 服务。

      • Here 是一个完整的例子
      • Here 是微软关于使用中间件的文档

      这就是中间件的样子。

      using System.Net;
      using System.Threading.Tasks;
      using Microsoft.AspNetCore.Http;
      
      namespace Authz.Opa
      {
          public class OpaAuthzMiddleware
          {
              private const string ForbiddenMessage = "Forbidden";
      
              private readonly RequestDelegate _next;
              private readonly IOpaService _opaService;
      
              public OpaAuthzMiddleware(RequestDelegate next, IOpaService service)
              {
                  _next = next;
                  _opaService= service;
              }
      
              public async Task InvokeAsync(HttpContext context)
              {
                  var enforceResult = await _opaService.RunAuthorizationAsync(context);
      
                  if (!enforceResult)
                  {
                      context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                      await context.Response.WriteAsync(ForbiddenMessage);
                      return;
                  }
      
                  await _next(context);
              }
          }
      }
      

      你会像这样在你的启动中实现它

      using Microsoft.AspNetCore.Builder;
      using Microsoft.AspNetCore.Hosting;
      using Microsoft.Extensions.DependencyInjection;
      using Microsoft.Extensions.Hosting;
      
      namespace Sample
      {
          public class Startup
          {
      
              public void ConfigureServices(IServiceCollection services)
              {
                  services.AddControllers();
                  services.AddRouting();
      
                  services.AddSingleton<IOpaService, OpaService>();
              }
      
      
              public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
              {
                  if (env.IsDevelopment())
                  {
                      app.UseDeveloperExceptionPage();
                  }
      
                  app.UseRouting();
      
                  app.UseMiddleware<OpaAuthzMiddleware>();
      
                  app.UseEndpoints(endpoints =>
                  {
                      endpoints.MapControllers();
                  });
              }
          }
      }
      

      使用 OPA 的 Wasm 编译

      OPA 具有可以将 Rego 策略编译成可执行 Wasm 模块的工具。他们提供文档here。 它目前正在开发中,但有一个在 .NET here 中使用它的示例。查看该回购问题部分下的讨论,看起来他们仍在解决一些问题。 您需要使用可用的 .NET 库之一来读取已编译的 Wasm 文件,但这被认为是 OPA 提供的最快的评估方法。

      【讨论】: