【问题标题】:.NET Core API Conditional Authentication attributes for Development & Production用于开发和生产的 .NET Core API 条件身份验证属性
【发布时间】:2017-05-25 10:44:52
【问题描述】:

长话短说,是否可以在我的 API 上放置基于环境的授权属性,以便在开发中关闭授权限制并在生产中重新打开?

我有一个单独的 Angular 2 项目,我希望使用它来调用 .NET Core API。我们创建了一个单独的项目,因此我们可以在 vscode 中打开 Angular 2 项目并调试打字稿。完成后,出于安全原因,我们将构建项目并将其放置在 .NET Core 项目中。

我们的问题是,在调试阶段,我们无法连接到 API,因为它们是两个独立的项目,而我们的 Angular 2 项目没有 Active Directory。 .NET Core 项目当前具有身份验证属性,并且不允许访问 (401) API。如果我们可以在开发过程中将其关闭并在生产过程中重新打开,那就太好了。

对于如何最好地解决这个问题,我也愿意接受任何其他建议。

[Authorize: (Only in Production)] <-- // something like this???
[Route("api/[controller]")]
public class TestController : Controller
{
    ...

【问题讨论】:

  • 为什么不创建您自己的自定义AuthorizeAttribute,只覆盖IsAuthorized?有plenty examples 说明如何做到这一点。

标签: c# asp.net api angular asp.net-core


【解决方案1】:

我最终得到了这个,可能会有所帮助:

    public class OnlyDebugModeAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        base.OnActionExecuted(context);
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
#if DEBUG

        //Ok
#else
        context.Result = new ForbidResult();
        return;
#endif

    }
}

然后应用到控制器上

[OnlyDebugMode]
[Route("api/[controller]")]
[ApiController]
public class DebugController : ControllerBase
{ 

【讨论】:

    【解决方案2】:

    这是我的解决方案:

    控制器的新属性:

    [AzureADAuthorize]

    AzureADAuthorize.cs:

    public class AzureADAuthorize : AuthorizeAttribute
        {
            public AzureADAuthorize() : base(AzureADPolicies.Name)
            {
            }
    
        }
    

    AzureADPolicies.cs:

    public static class AzureADPolicies
        {
            public static string Name => "AzureADAuthorizationRequired";
    
            public static void Build(AuthorizationPolicyBuilder builder)
                {
                    if (StaticRepo.Configuration.GetValue<bool>("EnableAuthorization") == true)
                    {
                        var section = StaticRepo.Configuration.GetSection($"AzureAd:AuthorizedAdGroups");
                        var groups = section.Get<string[]>();
                        builder.RequireClaim("groups", groups);
    
                    }
                    else if (StaticRepo.Configuration.GetValue<bool>("EnableAuthentication") == true)
                    {
                        builder.RequireAuthenticatedUser();
                    }else
                    {
                        builder
                        .RequireAssertion(_ => true)
                        .Build();
                    }             
                }
        }
    

    Startup.cs:

    //Authentication & Authorization
                #region AUTHENTICATION / AUTHORICATION
    
                StaticRepo.Configuration = Configuration;
    
    
                    services.AddAuthorization(options =>
                    {
                        options.AddPolicy(
                            AzureADPolicies.Name, AzureADPolicies.Build);
                    });
    
                services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
                 .AddAzureAD(options => Configuration.Bind("AzureAd", options));
    
                #endregion
    

    Appsettings.json:

     "EnableAuditLogging": false,
      "EnableAuthentication": true,
      "EnableAuthorization": false,
    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "https://MyDomain.onmicrosoft.com/",
        "TenantId": "b6909603-e5a8-497d-8fdb-7f10240fdd10",
        "ClientId": "6d09a1bf-4678-4aee-b67c-2d6df68d5324",
        "CallbackPath": "/signin-oidc",
        //Your Azure AD Security Group Object IDs that users needs to be member of to gain access
        "AuthorizedAdGroups": [
          "568bd325-283f-4909-9fcc-a493d19f98e8",
          "eee6d366-0f4d-4fca-9965-b2bc0770506d"
        ]
      }
    
    

    (这些是随机向导)

    现在你可以条件控制,如果你想有匿名访问,天蓝色广告认证,认证+组授权。您仍然需要在 azure 广告应用清单文件中设置一些内容才能使其正常工作,但我认为这超出了这里的范围。

    【讨论】:

      【解决方案3】:

      ASP.NET Core 授权基于策略。您可能已经看到,AuthorizeAttribute 可以采用策略名称,因此它知道需要满足哪些条件才能使请求获得授权。我建议您阅读有关该主题的great documentation

      回到你的问题,看起来你没有使用特定的策略,所以它使用默认策略,默认为requires the user to be authenticated

      您可以在Startup.cs 中更改该行为。如果您处于开发模式,您可以重新定义默认策略,使其没有任何要求:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddAuthorization(x =>
          {
              // _env is of type IHostingEnvironment, which you can inject in
              // the ctor of Startup
              if (_env.IsDevelopment())
              {
                  x.DefaultPolicy = new AuthorizationPolicyBuilder().Build();
              }
          });
      }
      

      更新

      im1dermike 在评论中提到AuthorizationPolicy 至少需要一个要求,正如我们可以看到的here。该代码最近没有引入,所以这意味着上面的解决方案一直被破坏。

      要解决这个问题,我们仍然可以利用AuthorizationPolicyBuilderRequireAssertion 方法并添加一个虚拟要求。这看起来像:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddAuthorization(x =>
          {
              // _env is of type IHostingEnvironment, which you can inject in
              // the ctor of Startup
              if (_env.IsDevelopment())
              {
                  x.DefaultPolicy = new AuthorizationPolicyBuilder()
                      .RequireAssertion(_ => true)
                      .Build();
              }
          });
      }
      

      这确保我们在授权策略中至少有一个要求,并且我们知道它总是会通过。

      【讨论】:

      • 当我在 .NETCoreApp 1.1 中实现此功能时,我收到 System.InvalidOperationException: 'AuthorizationPolicy must have at least one requirement.' 错误。
      • 是否有机会伪造/注入已登录的用户进行开发?
      • 这是否适用于 [Authorize] 的所有用法?如果您想选择适用的地方,您需要选择 Woot 的答案吗?
      • 这个过程在 Core 2.0 中不起作用,因为没有 DefaultPolicy 对象。有人在 2.0 中有解决方案吗?
      • @Rono DefaultPolicy 仍然存在于 ASP.NET Core 2.0 中,如您所见 in AuthorizationOptions on the rel/2.0.0 tag。你能仔细检查一下吗?
      猜你喜欢
      • 2020-10-15
      • 1970-01-01
      • 2017-04-27
      • 2018-05-13
      • 1970-01-01
      • 2021-04-12
      • 2020-10-08
      • 2021-06-15
      • 2019-11-28
      相关资源
      最近更新 更多