C# “Asp.net”;禁用";开发环境中的身份验证

C# “Asp.net”;禁用";开发环境中的身份验证,c#,asp.net-core,C#,Asp.net Core,是否可以在asp.net核心应用程序中“禁用”身份验证而不更改其逻辑 我有一个.net网站,它使用外部身份服务器应用程序进行身份验证。 无论如何,我希望在开发身份验证(ASPNETCORE_ENVIRONMENT=Development)时能够模拟身份验证,从而忽略授权属性,对所有操作进行访问 是否可以只模拟服务集合中的某些服务就这样做?在没有更多详细信息的情况下给出详细的答案是很棘手的,但我之前通过有条件地注册实现了这一点: 外部认证中间件 需要经过身份验证的请求的全局策略 它看起来像:

是否可以在asp.net核心应用程序中“禁用”身份验证而不更改其逻辑

我有一个.net网站,它使用外部身份服务器应用程序进行身份验证。 无论如何,我希望在开发身份验证(ASPNETCORE_ENVIRONMENT=Development)时能够模拟身份验证,从而忽略授权属性,对所有操作进行访问


是否可以只模拟服务集合中的某些服务就这样做?

在没有更多详细信息的情况下给出详细的答案是很棘手的,但我之前通过有条件地注册实现了这一点:

  • 外部认证中间件
  • 需要经过身份验证的请求的全局策略
它看起来像:

公共类启动
{
公共启动(IHostingEnvironment环境)
{
环境=环境;
}
公共IHostingEnvironment环境{get;}
public void配置服务(IServiceCollection服务)
{
services.AddMvc(x=>
{
如果(!Environment.IsDevelopment())
{
var authenticatedUserPolicy=new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()文件
.Build();
x、 添加(新的authorizedFilter(authorizedUserPolicy));
}
});
}
公共void配置(IApplicationBuilder应用程序、IHostingEnvironment环境、iLogger工厂)
{
app.UseStaticFiles();
如果(!Environment.IsDevelopment())
{
//注册外部认证中间件
}
app.UseMvc(路由=>
{
routes.MapRoute(
名称:“默认”,
模板:“{controller=Home}/{action=Index}/{id?}”);
});
}
}
在我的例子中,授权过滤器是全局应用的,因此MVC应用程序的每个操作都需要经过身份验证的用户

如果您对某些操作有不同的要求(细粒度的
[Authorize]
属性),那么您可以通过更改相关授权策略的构建方式来实现相同的结果。它们基本上可以不包含任何要求

AuthorizationPolicy yourCustomPolicy=null;
if(Environment.IsDevelopment())
{
yourCustomPolicy=new AuthorizationPolicyBuilder().Build();
}
其他的
{
yourCustomPolicy=new AuthorizationPolicyBuilder()
//链接合适的方法以满足您的需要
.Build();
}

我已在上找到解决此问题的方法

此代码必须工作:

if (env.IsDevelopment()) {
   services.AddMvc(opts =>
   {
      opts.Filters.Add(new AllowAnonymousFilter());
   });
} else {
   services.AddMvc();
}

您可能要考虑的另一个解决方案是使用iRealValueActudior。这意味着您可以保留所有现有的安全元素

public class DisableAuthenticationPolicyEvaluator : IPolicyEvaluator
{
    public async Task<AuthenticateResult> AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
    {
        // Always pass authentication.
        var authenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(), new AuthenticationProperties(), JwtBearerDefaults.AuthenticationScheme);
        return await Task.FromResult(AuthenticateResult.Success(authenticationTicket));
    }

    public async Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy policy, AuthenticateResult authenticationResult, HttpContext context, object resource)
    {
        // Always pass authorization
        return await Task.FromResult(PolicyAuthorizationResult.Success());
    }
}
公共类DisableAuthenticationPolicyEvaluator:IPolicyEvaluator
{
公共异步任务AuthenticateAsync(AuthorizationPolicy策略,HttpContext上下文)
{
//始终通过身份验证。
var authenticationTicket=new authenticationTicket(new ClaimsPrincipal()、new AuthenticationProperties()、JwtBearerDefaults.AuthenticationScheme);
返回wait Task.FromResult(AuthenticateResult.Success(authenticationTicket));
}
公共异步任务AuthorizationAsync(AuthorizationPolicy策略、AuthenticateResult authenticationResult、HttpContext上下文、对象资源)
{
//始终通过授权
返回wait Task.FromResult(PolicyAuthorizationResult.Success());
}
}
在Startup.cs中,确保它出现在ConfigureServices方法的顶部。例如

    public void ConfigureServices(IServiceCollection services)
    {
        if (env.IsDevelopment())
        {
            // Disable authentication and authorization.
            services.TryAddSingleton<IPolicyEvaluator, DisableAuthenticationPolicyEvaluator>();
        }
        ...
public void配置服务(IServiceCollection服务)
{
if(env.IsDevelopment())
{
//禁用身份验证和授权。
services.TryAddSingleton();
}
...
如果您使用的是Core 3.1并且希望使用WebApplicationFactory,则可以执行以下操作,而不是Startup.cs(并感谢下面的注释):

public class MyWebApplicationFactory : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureTestServices(services =>
        {
            // Disable Authentication.
            services.RemoveAll<IPolicyEvaluator>();
            services.AddSingleton<IPolicyEvaluator, DisableAuthenticationPolicyEvaluator>();
        });
    }
}
公共类MyWebApplicationFactory:WebApplicationFactory
{
受保护的覆盖无效配置WebHost(IWebHostBuilder)
{
builder.ConfigureTestServices(服务=>
{
//禁用身份验证。
services.RemoveAll();
services.AddSingleton();
});
}
}

在更新到net core 3.1时,mvc
AllowAnonymousFilter
不再适用于我们。我们发现有条件地添加自定义
IAAuthorizationHander
是有条件地绕过身份验证的最简单方法

例如

//
///此授权处理程序将绕过所有要求
/// 
公共类AllowAnonymous:IAAuthorizationHandler
{
公共任务HandleAsync(AuthorizationHandlerContext上下文)
{
foreach(context.PendingRequirements.ToList()中的IAAuthorizationRequirements需求)
success(requirement);//只需传递所有需求
返回Task.CompletedTask;
}
}
然后在
Startup.ConfigureServices
中有条件地注册此处理程序

private只读IWebHostEnvironment\u env;
公共启动(IWebHostEnvironment env)
{
_env=env;
}
public void配置服务(IServiceCollection服务)
{
{...}
//允许绕过身份验证
如果(_env.IsDevelopment())
services.AddSingleton();
}
注意
AddAuthentication
AddAuthentication
服务仍然按照产品代码注册和配置(这很好)


为了让我们的单元测试绕过身份验证,我们添加了一个新的匿名测试库,其中包含一个startup类,该类在没有任何条件的情况下添加了这一行。非常简单!

在ASP.NET Core 3.x及更高版本中,您可以使用扩展方法在
startup.Configure()
中添加到端点

endponts.MapControllers()
示例:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...
    app.UseEndpoints(endpoints =>
    {
        var hiEndpoint = endpoints
            .MapGet("/hi", async context => await context.Response.WriteAsync("Hello!"))
            .WithMetadata(new AuthorizeAttribute());
        
        if (env.IsDevelopment())
            hiEndpoint.WithMetadata(new AllowAnonymousAttribute());
    });
}
公共的