【问题标题】:Bypass Authorize Attribute in .Net Core for Release Version绕过 .Net Core 中的授权属性以获取发布版本
【发布时间】:2016-12-06 23:07:25
【问题描述】:

有没有办法在 asp.net 核心中“绕过”授权?我注意到 Authorize 属性不再具有 AuthorizeCore 方法,您可以使用该方法来决定是否继续进行身份验证。

Pre .net core 你可以这样做:

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    // no auth in debug mode please
    #if DEBUG
       return true;
    #endif

    return base.AuthorizeCore(httpContext);
}

我希望我不会遗漏一些明显的东西,但如果需要的话,能够跳过 DEBUG 中的身份验证工作流程会很好。我只是无法为 .net core 找到它

【问题讨论】:

  • 你不应该派生自AuthorizeAttribute。查看基于策略的授权。 docs.asp.net/en/latest/security/authorization/policies.html 您可以编写具有多个处理程序的需求,并使用不同的处理程序作为备用,以防第一个未授权(除非第一个调用 context.Failed())。后备示例可以在这里找到docs.asp.net/en/latest/security/authorization/…
  • 感谢@Tseng,这是很好的信息。然而,令人沮丧的是,我们似乎失去了简单地根据您是否处于调试或发布模式来打开/关闭身份验证的能力。所以我是否正确假设我可以将我的 [Authorize] 属性包装在#if DEBUG 指令周围 将一些策略/要求/处理程序整合在一起中心位置?那会是什么样子?
  • 嗯,是的。但是没有什么能阻止您创建一个基础需求类,您的所有其他需求都来自该类,并在那里添加此检查
  • 添加了一个关于如何使用基本需求处理程序的示例
  • 这里的解决方案对我来说效果很好。 stackoverflow.com/a/40156927/5329320

标签: c# asp.net-core


【解决方案1】:

对于仍然需要获取假用户对象的人,以下解决方案可以解决问题:

app.Use(async (context, next) =>
{
    context.User = new System.Security.Claims.ClaimsPrincipal(new ClaimsIdentity(new Claim[]
    {
        new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", Guid.NewGuid().ToString()),
    }, "test"));
    await next.Invoke();
});

app.UseMvc();

如果 DefaultScheme 是“Cookies”,该解决方案应该可以工作。

【讨论】:

  • 这对于调试 API 来说非常棒。如果你把它放在 UseAuthentication 和 UseAuthorization 之间,你可以有条件地添加一个带有任何你喜欢的声明的假用户。
【解决方案2】:

您可以定义自己的禁用授权的处理程序:

public class DisableAuthorizationHandler<TRequirement> : AuthorizationHandler<TRequirement>
    where TRequirement : IAuthorizationRequirement
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement)
    {
        context.Succeed(requirement);

        return Task.CompletedTask;
    }
}

然后注册:

    public void ConfigureServices(IServiceCollection services)
    {
    //...
#if DEBUG
    services.AddTransient<IAuthorizationHandler, DisableAuthorizationHandler<IAuthorizationRequirement>>();
#endif
    //...
    }

【讨论】:

    【解决方案3】:

    扩展 John_J 的答案:

        public void ConfigureServices(IServiceCollection services)
        {
            ...
    
    #if DEBUG
            services.AddMvc(opts =>
            {
                opts.Filters.Add(new AllowAnonymousFilter());
            });
    #else
            services.AddMvc();
    #endif
        }
    

    【讨论】:

      【解决方案4】:

      只需添加一个匿名过滤器即可,简单易行。

         services.AddMvc(opts =>
         {
            opts.Filters.Add(new AllowAnonymousFilter());
         });
      

      参考:https://www.illucit.com/asp-net/asp-net-core-2-0-disable-authentication-development-environment/

      【讨论】:

      【解决方案5】:

      正如 cmets 中所指出的,您可以为所有需求处理程序创建一个基类。

      public abstract class RequirementHandlerBase<T> : AuthorizationHandler<T> where T : IAuthorizationRequirement
      {
          protected sealed override Task HandleRequirementAsync(AuthorizationHandlerContext context, T requirement)
          {
      #if DEBUG
              context.Succeed(requirement);
      
              return Task.FromResult(true);
      #else
              return HandleAsync(context, requirement);
      #endif
          }
      
          protected abstract Task HandleAsync(AuthorizationHandlerContext context, T requirement);
      }
      

      然后从这个基类派生您的需求处理程序。

      public class AgeRequirementHandler : RequirementHandlerBase<AgeRequirement>
      {
          protected override HandleAsync(AuthorizationHandlerContext context, AgeRequirement requirement)
          {
              ... 
          }
      }
      
      public class AgeRequirement : IRequrement 
      {
          public int MinimumAge { get; set; }
      }
      

      然后注册它。

      services.AddAuthorization(options =>
      {
          options.AddPolicy("Over18",
                            policy => policy.Requirements.Add(new AgeRequirement { MinimumAge = 18 }));
      });
      

      【讨论】:

        【解决方案6】:

        我想到了两种可能的解决方案。

        首先是使用假的Authentication Middleware。您可以创建一个伪造的身份验证中间件,例如this。你的Startup.cs 应该是这样的(你应该注意虚假服务):

        private IHostingEnvironment _env;
        
        public Startup(IHostingEnvironment env)
        {
          _env = env;
          // other stuff
        }
        
        public void ConfigureServices(IServiceCollection services)
        {
          // ...
          if (_env.IsDevelopment())
          {
            // dev stuff
            services.AddTransient<ISomeService, FakeSomeService>();
          }
          else
          {
            // production stuff
            services.AddTransient<ISomeService, SomeService>();
          }
        }
        
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
             if (env.IsDevelopment())
             {
                 app.UseFakeAuthentication();
             }
             else
             {
                 app.UseRealAuthentication();
             }
        }
        

        第二 是使用多个处理程序(如@Tseng 所说)。在这种情况下,我会写这样的东西:

        private IHostingEnvironment _env;
        
        public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
        {
          _env = env;
          // other stuff
        }
        
        public void ConfigureServices(IServiceCollection services)
        {
          // ...
          if (_env.IsDevelopment())
          {
            // dev stuff
             services.AddSingleton<IAuthorizationHandler, FakeAuthorizationHandler>();
          }
          else
          {
            // production stuff
            services.AddSingleton<IAuthorizationHandler, RealAuthorizationHandler>();
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-12-03
          • 2021-07-19
          • 2017-09-16
          • 2017-05-22
          • 2020-07-21
          • 2019-07-31
          • 2021-05-11
          相关资源
          最近更新 更多