How do I integration test a ASP 5/Core Web API with [Authorize] Attributes
<p>I currently have an ASP 5/ASP Core Web API that I need to integration test with the OWIN Test Server.</p>

<p>The problem is that I use IdentityServer as the authorization server in production and I do not want to include the authorization as part of my integration testing.</p>

<p>This is the Startup.cs of the API:</p>



<pre><code>public Startup(IHostingEnvironment env)
{
    // Set up configuration sources.
    IConfigurationBuilder builder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true);

    if (env.IsEnvironment("Development"))
    {
        // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
        builder.AddApplicationInsightsSettings(developerMode: true);
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build().ReloadOnChanged("appsettings.json");
}

public IConfigurationRoot Configuration { get; set; }

// This method gets called by the runtime. Use this method to add services to the container
public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddApplicationInsightsTelemetry(Configuration);

    ConfigureEntityFrameworkDatabase(services, Configuration);

    services.AddIdentity&lt;IdentityUser, IdentityRole&gt;()
        .AddEntityFrameworkStores&lt;HoehenSuchtIdentityDbContext&gt;()
        .AddDefaultTokenProviders();

    ConfigureMvc(services);

    // register autofac as dependency resolver
    ContainerBuilder containerBuilder = new ContainerBuilder();

    // register all required autofac modules
    RegisterAutofacModules(containerBuilder);

    // register all automapper mappings as di services so there dependencies can be resolved
    ConfigureAutomapper(containerBuilder);

    ConfigureSwagger(services);

    // copy all asp core dependency injection registrations to autofac
    containerBuilder.Populate(services);
    IContainer container = containerBuilder.Build();

    return container.Resolve&lt;IServiceProvider&gt;();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
</code></pre>



<pre><code>public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }

    // make sure the database was created and all migrations applied
    MigrateDatabase(app);
    app.ApplicationServices.GetService&lt;HoehenSuchtDbContext&gt;().EnsureSeedData(env);

    app.UseIISPlatformHandler();

    app.UseApplicationInsightsRequestTelemetry();
    app.UseApplicationInsightsExceptionTelemetry();

    ConfigureIdentityServer(app, Configuration);

    app.UseStaticFiles();

    app.UseMvc();

    //app.UseSwaggerGen(/*routeTemplate: "docs/{apiVersion}/swagger.json"*/);
    //app.UseSwaggerUi(/*baseRoute: "docs", swaggerUrl: "docs/v1/swagger.json"*/);
}

public static Action&lt;IServiceCollection, IConfigurationRoot&gt; ConfigureEntityFrameworkDatabase = (services, config) =&gt;
{
    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext&lt;HoehenSuchtDbContext&gt;(builder =&gt;
            builder.UseSqlServer(config["Data:DefaultConnection:ConnectionString"]))
        .AddDbContext&lt;HoehenSuchtIdentityDbContext&gt;(builder =&gt;
            builder.UseSqlServer(config["Data:IdentityConnection:ConnectionString"]));
};

public static Action&lt;IServiceCollection&gt; ConfigureMvc = services =&gt;
{
    services.AddMvc().AddControllersAsServices(new List&lt;Assembly&gt; { typeof(Startup).GetTypeInfo().Assembly });
};
</code></pre>

<p>I already tried registering a special test middleware that in theory should authenticate and set a claims principal. But somewhere down the OWIN pipeline the authentication is denied and I get a 401 error code.</p>

<p>This is how I setup the OWIN Test Server:</p>



<pre><code>Startup.MigrateDatabase = app =&gt;
{
    app.ApplicationServices.GetService&lt;HoehenSuchtDbContext&gt;().Database.EnsureCreated();
};
Startup.ConfigureEntityFrameworkDatabase = ApiTestServer.ConfigureInMemoryDatabase;
Startup.ConfigureIdentityServer = (app, config) =&gt;
{
    app.ApplicationServices.GetService&lt;HoehenSuchtDbContext&gt;().EnsureSeedData(new HostingEnvironment {EnvironmentName = "development" });

    app.UseMiddleware&lt;AuthenticatedTestRequestMiddleware&gt;();
};
Server = new TestServer(TestServer.CreateBuilder().UseStartup&lt;Startup&gt;());
</code></pre>

<p>And this is my custom <code>AuthenticatedTestRequestMiddleware</code>:</p>



<pre><code>public class AuthenticatedTestRequestMiddleware
{
    public const string TestingCookieAuthentication = "TestCookieAuthentication";
    public const string TestingHeader = "X-Integration-Testing";
    public const string TestingHeaderValue = "78EAAA45-E68B-43C7-9D12-3A5F1E646BD5";

    private readonly RequestDelegate _next;

    public AuthenticatedTestRequestMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Headers.Keys.Contains(TestingHeader) &amp;&amp; context.Request.Headers[TestingHeader].First().Equals(TestingHeaderValue))
        {
            // fake authenticated the user
            ClaimsIdentity claimsIdentity = new ClaimsIdentity();
            claimsIdentity.AddClaims(new List&lt;Claim&gt;
            {
                new Claim(ClaimTypes.Name, "admin"),
                new Claim(ClaimTypes.NameIdentifier, UserSeedData.AdminUserId)
            });
            ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
            context.User = claimsPrincipal;
        }

        await _next(context);
    }
}
</code></pre>

<p>The principal is set and exists in the database with the given ID, but after I call <code>next(context)</code> I get an <code>401 Unauthorized</code> result.</p>

<p>How can I successfully fake authenticate the user and bypass the [Authorize] while also setting the current User for the HttpRequest?</p>

<p><strong>UPDATE:</strong>
If I register my own CookieAuthentication handler like that:</p>



<pre><code>app.UseCookieAuthentication(options =&gt;
{
    options.AuthenticationScheme = AuthenticatedTestRequestMiddleware.TestingCookieAuthentication;
    options.AutomaticAuthenticate = true;
    options.AutomaticChallenge = true;
});
</code></pre>

<p>I get the <code>302 Redirect</code> to the login page. The signin however is working correctly when I use this inside the TestMiddleware <code>await context.Authentication.SignInAsync(TestingCookieAuthentication, claimsPrincipal)</code></p>