.NET Core API 用于开发和生产的条件身份验证属性

问题描述 投票:0回答:4

长话短说,是否可以在我的 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
{
    ...
c# asp.net api angular asp.net-core
4个回答
34
投票

ASP.NET Core 授权是基于策略的。正如您可能已经看到的,

AuthorizeAttribute
可以采用策略名称,以便它知道需要满足哪些条件才能授权请求。我建议您阅读有关该主题的优秀文档

回到您的问题,看来您没有使用特定策略,因此它使用默认策略,默认情况下要求用户进行身份验证

您可以在

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 中看到的那样。该代码不是最近引入的,所以这意味着上面的解决方案一直被破坏。

为了解决这个问题,我们仍然可以利用 RequireAssertion

AuthorizationPolicyBuilder
 方法并添加虚拟需求。这看起来像:

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();
        }
    });
}

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


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
{ 

0
投票

这是我的解决方案:

控制器的新属性:

[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();
                }             
            }
    }

启动.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

应用程序设置.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 ad 身份验证、身份验证+群组授权,您可以进行条件控制。您仍然需要在 Azure 广告应用清单文件中设置一些内容才能使其正常工作,但我认为它超出了此处的范围。


0
投票

如果您希望策略仅适用于特定的角色、特定的控制器,特别是环境。您可以添加新的授权策略(使用您喜欢的任何逻辑),然后在控制器的授权属性中使用它。

所以而不是以下内容在所有环境中运行:

[Authorize(Roles = "admin")]
public class AdminController : ControllerBase

将以下设置添加到您的

Program.cs
启动类中:

builder.Services.AddAuthorizationBuilder()
    .AddPolicy("RequireAdminRoleInProd", policy =>
    {
        if (builder.Environment.IsProduction())
        {
            policy.RequireRole("admin");
        }
        else
        {
            policy.RequireAssertion(_ => true);

        }
    });

然后在您的控制器中添加授权策略:

[Authorize(Policy = "RequireAdminRoleInProd")]
public class AdminController : ControllerBase

这在 aspnet core 中运行良好,它消除了

AuthorizeAttribute
曾经工作的重载。

进一步阅读

© www.soinside.com 2019 - 2024. All rights reserved.