2016-08-01 87 views
3

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

预.NET的核心,你可以做这样的事情:

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

    return base.AuthorizeCore(httpContext); 
} 

我希望我不是失去了一些东西公然明显,但它会很高兴能够在必要时跳过身份验证工作流程DEBUG。我只是一直无法找到它.net核心

+2

你不应该从'AuthorizeAttribute'派生。研究基于策略的授权。 https://docs.asp.net/en/latest/security/authorization/policies.html您可以编写具有多于1个处理程序的需求,并在第一个不授权的情况下使用不同的处理程序作为回退(除非第一个调用'context.Failed()')。后备示例可以在这里找到https://docs.asp.net/en/latest/security/authorization/policies.html#why-would-i-want-multiple-handlers-for-a-requirement – Tseng

+0

谢谢@Tseng那就是好的信息。然而,令人沮丧的是,看起来好像我们失去了根据是否在DEBUG或RELEASE模式下开启/关闭auth的能力。所以我正确地假设,我可以在#if DEBUG指令**或**上连接一些策略/需求/处理程序,以在一个中心位置执行所有**我的[授权]属性**。那该怎么看? – SteveT

+0

嗯,是的。但是没有什么能阻止你创建一个基本需求类,其中你的所有其他需求都来自于这个基础需求,并且在那里添加这个检查 – Tseng

回答

2

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

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

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

第一个是使用假的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>(); 
    } 
}