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

时间:2017-01-10 20:03:31

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

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

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

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

我也对如何最好地解决这个问题提出任何其他建议。

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

3 个答案:

答案 0 :(得分:16)

ASP.NET核心授权基于策略。您可能已经看到,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。该代码最近没有被引入,所以这意味着上面的解决方案一直都被打破了。

要解决此问题,我们仍然可以利用AuthorizationPolicyBuilder的{​​{3}}方法并添加虚拟要求。这看起来像是:

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

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广告身份验证,身份验证+组授权。您还需要在Azure广告应用程序清单文件中设置一些内容才能使其正常工作,但我认为这不在此处范围内。