I currently have the ASP 5 / ASP Core Web API that I need to test integration with the OWIN test server.
The problem is that I am using IdentityServer as an authorization server in production, and I do not want to include authorization as part of my integration testing.
This is the Startup.cs API:
public Startup(IHostingEnvironment env)
{
IConfigurationBuilder builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true);
if (env.IsEnvironment("Development"))
{
builder.AddApplicationInsightsSettings(developerMode: true);
}
builder.AddEnvironmentVariables();
Configuration = builder.Build().ReloadOnChanged("appsettings.json");
}
public IConfigurationRoot Configuration { get; set; }
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry(Configuration);
ConfigureEntityFrameworkDatabase(services, Configuration);
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<HoehenSuchtIdentityDbContext>()
.AddDefaultTokenProviders();
ConfigureMvc(services);
ContainerBuilder containerBuilder = new ContainerBuilder();
RegisterAutofacModules(containerBuilder);
ConfigureAutomapper(containerBuilder);
ConfigureSwagger(services);
containerBuilder.Populate(services);
IContainer container = containerBuilder.Build();
return container.Resolve<IServiceProvider>();
}
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();
}
MigrateDatabase(app);
app.ApplicationServices.GetService<HoehenSuchtDbContext>().EnsureSeedData(env);
app.UseIISPlatformHandler();
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
ConfigureIdentityServer(app, Configuration);
app.UseStaticFiles();
app.UseMvc();
}
public static Action<IServiceCollection, IConfigurationRoot> ConfigureEntityFrameworkDatabase = (services, config) =>
{
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<HoehenSuchtDbContext>(builder =>
builder.UseSqlServer(config["Data:DefaultConnection:ConnectionString"]))
.AddDbContext<HoehenSuchtIdentityDbContext>(builder =>
builder.UseSqlServer(config["Data:IdentityConnection:ConnectionString"]));
};
public static Action<IServiceCollection> ConfigureMvc = services =>
{
services.AddMvc().AddControllersAsServices(new List<Assembly> { typeof(Startup).GetTypeInfo().Assembly });
};
I already tried to register a special test middleware, which theoretically should authenticate and install the main application. But somewhere down the OWIN pipeline, authentication is rejected and I get error code 401.
This is how I install the OWIN test server:
Startup.MigrateDatabase = app =>
{
app.ApplicationServices.GetService<HoehenSuchtDbContext>().Database.EnsureCreated();
};
Startup.ConfigureEntityFrameworkDatabase = ApiTestServer.ConfigureInMemoryDatabase;
Startup.ConfigureIdentityServer = (app, config) =>
{
app.ApplicationServices.GetService<HoehenSuchtDbContext>().EnsureSeedData(new HostingEnvironment {EnvironmentName = "development" });
app.UseMiddleware<AuthenticatedTestRequestMiddleware>();
};
Server = new TestServer(TestServer.CreateBuilder().UseStartup<Startup>());
And this is my custom AuthenticatedTestRequestMiddleware:
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) && context.Request.Headers[TestingHeader].First().Equals(TestingHeaderValue))
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity();
claimsIdentity.AddClaims(new List<Claim>
{
new Claim(ClaimTypes.Name, "admin"),
new Claim(ClaimTypes.NameIdentifier, UserSeedData.AdminUserId)
});
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
context.User = claimsPrincipal;
}
await _next(context);
}
}
, next(context) 401 Unauthorized.
[], HttpRequest?
UPDATE:
CookieAuthentication :
app.UseCookieAuthentication(options =>
{
options.AuthenticationScheme = AuthenticatedTestRequestMiddleware.TestingCookieAuthentication;
options.AutomaticAuthenticate = true;
options.AutomaticChallenge = true;
});
302 Redirect . , , TestMiddleware await context.Authentication.SignInAsync(TestingCookieAuthentication, claimsPrincipal)