微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Asp.net core,在调试时,绕过授权

如何解决Asp.net core,在调试时,绕过授权

我有一个测试网站,它在整个控制器级别使用 aspnetCore [AuthorizeAttribute] 以确保只有经过身份验证的用户才能访问该网站。

在调试和测试新功能的同时,我们不断地必须注释掉每个控制器中的属性,我知道这很容易忘记,并且可能有一天会被合并。

我们在检查之前是否连接了调试器方面取得了很大的成功......我想知道我应该指定哪个 AuthenticationScheme 以允许匿名,只有在调试时。

我扩展了基本 AuthorizeAttribute 以便我可以轻松地在一些代码中填充。

public class MyAppAuthorizeAttribute : AuthorizeAttribute
    {
        public MyAppAuthorizeAttribute()
            : base(Policies.MyAppAuthorize)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                Console.WriteLine("Skipping auth for debug");        //we hit this line but...
                this.AuthenticationSchemes = AllowAnonymousAttribute //this setting does not work
            }
            else
            {
                this.AuthenticationSchemes = "IntegratedWindowsAuthentication";
            }
            
        }
    }

解决方法

看起来很适合IWebHostingEnvironment.IsDevelopment()

public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
    if (!env.IsDevelopment())
    {
        app.UseAuthentication();
        app.UseAuthorization(); // maybe optional,depends on your case
    }
    ...
,

在某些情况下,您的要求可能是必要的,即要求用户进行身份验证但实际上并未在代码中引用(例如:代码未访问有关当前身份的任何信息,尤其是与用户的业务模型相关的信息) )。 因此,我假设您已经意识到这一点,因为以下内容将仅删除在开发环境中运行代码时检查已验证用户的要求。还有另一种自动登录虚拟用户的方法,在某些情况下可能会更好。

这是第一个解决方案,它只配置了一个不包含 DenyAnonymousAuthorizationRequirement 的默认策略(这是默认策略中包含的唯一要求)。这意味着如果您在某处使用了多个策略(使用 AuthorizeAttribute),则只会忽略默认值(在调试时)。第二种解决方案(稍后显示)可能更适合这种情况。

//inject IHostingEnvironment in the Startup constructor
public Startup(IConfiguration configuration,IHostingEnvironment env){
   HostingEnvironment = env;
}
public IHostingEnvironment HostingEnvironment { get; }

//in the ConfigureServices method in Startup.cs
services.AddAuthorization(o => {
    if (HostingEnvironment.IsDevelopment()){
       o.DefaultPolicy = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme)
                         //there should be at least 1 requirement
                         //here we add a simple always-passed assertion
                         .RequireAssertion(e => true).Build();
    }         
    //...
});

我们需要使用 IHostingEnvironment(在 .net core 2.2 中,从 3.0 开始,我们有 2 个替代方案 IWebHostEnvironmentIHostEnvironment)所以我们将它注入到 Startup 构造函数和将其存储在只读属性中(如上所示)。还有一种方法是尝试像这样直接获取 ASPNETCORE_ENVIRONMENT 变量:

var isDevelopment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";

这是第二种解决方案,其中您使用自定义全局 IAsyncAuthorizationFilter 自动登录虚拟用户(因此它始终对所有请求进行身份验证)。

public class AllowAnonymousFilterAttribute : Attribute,IAsyncAuthorizationFilter
{
    readonly IHostingEnvironment _hostingEnvironment;
    public AllowAnonymousFilterAttribute(IHostingEnvironment env){
       _hostingEnvironment = env;
    }
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        if (_hostingEnvironment.IsDevelopment() && !context.HttpContext.User.Identity.IsAuthenticated)
        {
            //prepare a dummy user to auto sign-in
            HttpContext.User = new ClaimsPrincipal(new[] {
                new ClaimsIdentity(new []{ new Claim(ClaimTypes.NameIdentifier,"admin")},CookieAuthenticationDefaults.AuthenticationScheme)
            });
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,HttpContext.User);
        }
    }
}

全局注册过滤器,这里我为.net core 2.2编写代码:

services.AddMvc(o => {
     //register the filter only for development (should be debugging)
     if (HostingEnvironment.IsDevelopment()){
       o.Filters.Add<AllowAnonymousFilterAttribute>();
     }
     //...
});

我确信还有一些其他的解决方案,但我在此介绍的内容相当简单且足以满足您的目的。

P/S:我在上面介绍的第一个解决方案适用于 .net core 2.2(实际上目前我无法访问较新版本的 .net core , 真遗憾)。对于较新的版本,Authorization 中间件是独立的,因此您可能只是不按照另一个答案的建议在 .UseAuthorization() 方法中调用 Configure 中间件(当然仅适用于开发环境)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。