C# 在ASP.Net核心集成测试中模拟IIS应用程序池标识

C# 在ASP.Net核心集成测试中模拟IIS应用程序池标识,c#,asp.net-core,integration-testing,asp.net-core-webapi,C#,Asp.net Core,Integration Testing,Asp.net Core Webapi,我正在尝试为我正在编写的ASP.NETCore3.1API编写集成测试。我使用WebApplicationFactory类来创建一个用于调用API的HttpClient _Factory = new WebApplicationFactory<Startup>() .WithWebHostBuilder(b => { b.ConfigureTestServices(services =>

我正在尝试为我正在编写的ASP.NETCore3.1API编写集成测试。我使用WebApplicationFactory类来创建一个用于调用API的HttpClient

_Factory = new WebApplicationFactory<Startup>()
            .WithWebHostBuilder(b =>
            {
                b.ConfigureTestServices(services =>
                {
                    services.AddAuthentication("Test")
                        .AddScheme<AuthenticationSchemeOptions, MyAuthHandler>("Test", options => { });
                    RegisterTestServices(services);
                });
            });
\u工厂=新的WebApplicationFactory()
.WithWebHostBuilder(b=>
{
b、 ConfigureTestServices(服务=>
{
服务。添加身份验证(“测试”)
.AddScheme(“测试”,选项=>{});
注册测试服务(服务);
});
});
与:

公共类MyAuthHandler:AuthenticationHandler
{
公共MyAuthHandler(IOptionsMonitor选项、iLogger工厂记录器、UrlEncoder编码器、ISystemClock时钟):基本(选项、记录器、编码器、时钟){}
受保护的覆盖任务handleAuthenticateAync()
{
var索赔=新[]{新索赔(“首选用户名”、“mchu”)};
var标识=新的索赔实体(索赔,“测试”);
var principal=新的ClaimsPrincipal(身份);
var票证=新的认证票证(主体,“测试”);
var结果=AuthenticateResult.Success(票证);
返回Task.FromResult(结果);
}
}
这使我能够成功地检索一个HttpClient,它可以调用我的端点(用[Authorize]修饰),这样我就不会得到401个错误。但是,由于尝试访问网络共享时出现权限问题,我的一些测试失败

在实际的IIS部署中,我们的应用程序池将使用对这些共享具有读/写访问权限的标识

我能做些什么来确保我的API代码运行时具有访问这些受保护资源的权限吗?我们现有的集成测试代码(针对非ASP.Net核心代码——这是一个转换)通过在管理员模拟上下文中执行特定操作来解决这个问题。对于这些新的测试,我也可以这样做


然而,我还没有完全了解WebApplicationFactory(或者ASP.Net核心中间件管道的任何部分,真的),我不确定我将如何进行这项工作。

ASP.Net核心不实现模拟。应用程序使用应用程序池或进程标识以应用程序的标识运行所有请求。如果应用程序应代表用户执行操作,请在Startup.Configure中的终端内联中间件中使用WindowsIdentity.RunImpersonated。在此上下文中运行单个操作,然后关闭上下文


更多详细信息,请参阅此

谢谢。我确实在我的尝试中发现了这篇文章,所以解决了这个问题,我的解决方案和您描述的差不多。唯一的区别是,我只在使用自定义“测试”开发环境时配置中间件,因为在生产环境中,IIS的宿主提供了正确的行为。然而,我很好奇什么是“正常”用例,以至于大多数ASP.Net核心集成测试代码的过程不需要应用程序池用户的权限,而这些权限可能与运行测试的用户的权限不同。
public class MyAuthHandler: AuthenticationHandler<AuthenticationSchemeOptions>
{
    public MyAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) { }
    protected override  Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var claims = new[] {new Claim("preferred_username", "mchu")};
        var identity = new ClaimsIdentity(claims, "Test");
        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, "Test");

        var result = AuthenticateResult.Success(ticket);

        return Task.FromResult(result);
    }
}