【问题标题】:Authorization Attribute Dependent on Runtime Configuration授权属性依赖于运行时配置
【发布时间】:2019-10-10 08:11:33
【问题描述】:

我有一个这样配置的 .Net Core 3.0 Web API:

services.AddAuthentication(x =>
  {
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  })
  .AddJwtBearer(x =>
  {
    ...
  });

services.AddAuthorizationCore(options =>
  {
    options.FallbackPolicy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
  });

我在控制器中启用它,例如:

[Authorize(Roles = "Admin,Technician")]
public IActionResult CreateFoo([FromBody] Foo foo)

使用[AllowAnonymous] 也禁用了一些 api 端点。

本产品支持多种环境,一个端点需要匿名或授权依赖于运行时变量;当前使用自定义“ASPNETCORE_ENVIRONMENT”选项。

我看到了来自 .net 安全人员的 this 评论,但如果我实施自定义策略,它会禁止匿名访问。

如果应用程序在特定环境中运行,允许匿名访问的最简单方法是什么?

【问题讨论】:

    标签: c# asp.net asp.net-core authorization asp.net-core-3.0


    【解决方案1】:

    如果我理解您的问题,那么您可以创建一个自定义属性并在应用程序在某个环境中运行时始终授予用户访问权限?

       public class CustomEnvRequirement : AuthorizationHandler<CustomEnvRequirement>, IAuthorizationRequirement
        {
            protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomEnvRequirement requirement)
            {
                string currentEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
    
                // Allow Anonymous when the current env is development.
                if (currentEnv.ToLowerInvariant().Equals("development"))
                {
                    context.Succeed(requirement);
                }
                else if (currentEnv.ToLowerInvariant().Equals("production"))
                {
                    // TODO: add more authorization logic.
    
                }
                return Task.CompletedTask;
            }
        }
    

    这是要添加的自定义属性

     [Authorize(Policy = "CustomEnv")]
    
            public IActionResult Index()
            {
                return this.View();
            }
    

    另外,请务必在 startup.cs 中进行配置

      services.AddAuthorization(options =>
                {
                    options.AddPolicy("CustomEnv",
                        policy => policy.Requirements.Add(new CustomEnvRequirement()));
                });
    

    【讨论】:

    • 我已经尝试过了,但仍然需要认证。
    • 这基本上是答案,但要使其充分发挥作用,需要为没有 RequireAuthenticatedUser 的 DefaultPolicy 创建一个新的 AuthorizationPolicyBuilder。
    【解决方案2】:

    AuthorizeAttribute 只是 AuthorizationFilterAttribute 的一个实现。您可以创建自己的实现来绕过某些环境的身份验证:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class EnvironmentSpecificAutorizeAttribute : AuthorizeAttribute
    {
        public string AllowAnonymousEnvironment { get; set; }
    
        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            // if currentEnv == AllowAnonymousEnvironment 
            //    return 
            // else
            //    base.HandleUnauthorizedRequest(actionContext);
        }
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            // same logic as above
            base.OnAuthorization(actionContext);
        }
    
        public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
        {
            // same logic as above
            return base.OnAuthorizationAsync(actionContext, cancellationToken);
        }
    }
    

    您可以在this thread找到其他建议

    【讨论】:

    • 这不适用于 AspNet Core,但感谢您提供的链接。
    • 授权属性来源来自 webapi,第二个链接是核心文档,为什么这不适用?您可能需要覆盖核心中的不同方法,但该方法适用。如果是这样,请随时提出修改建议。
    猜你喜欢
    • 2020-08-31
    • 2017-02-07
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多