В производстве я использую OKTA для аутентификации и авторизации (open id connect). Я изо всех сил пытался добраться до точки, где я могу написать интеграционные тесты.
В моем тестовом проекте у меня есть TestStartup
класс:
public class TestStartup
{
#region Constructors
public TestStartup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.tests.json", false, true)
.AddEnvironmentVariables();
builder.Build();
}
#endregion
#region Public Methods
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultAuthenticateScheme = "Test Scheme";
sharedOptions.DefaultChallengeScheme = "Test Scheme";
})
.AddTestAuth(o => { });
services.AddAuthorization(options =>
{
options.AddPolicy(AuthorizationPolicy.DataProvider,
policy => policy.Requirements.Add(new RolesRequirement(Roles.DataProvider, Roles.Admin)));
options.AddPolicy(AuthorizationPolicy.DataProcessor,
policy => policy.Requirements.Add(new RolesRequirement(Roles.DataProcessor, Roles.Admin)));
options.AddPolicy(AuthorizationPolicy.ClientDataSubmissions,
policy => policy.Requirements.Add(new RolesRequirement(Roles.DataProvider,
Roles.DataProcessor,
Roles.Admin)));
options.AddPolicy(AuthorizationPolicy.Admin,
policy => policy.Requirements.Add(new RoleRequirement(Roles.Admin)));
options.AddPolicy(AuthorizationPolicy.Client,
policy => policy.Requirements.Add(new RoleRequirement(Roles.Client)));
options.AddPolicy(AuthorizationPolicy.Everyone,
policy => policy.Requirements.Add(new RoleRequirement(Roles.Everyone)));
});
services.AddSingleton<IAuthorizationHandler, RoleAuthorizationHandler>();
services.AddSingleton<IAuthorizationHandler, RolesAuthorizationHandler>();
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
//app.UseMiddleware<AuthenticatedTestRequestMiddleware>();
app.UseMvc();
}
#endregion
}
public class TestAuthenticationHandler : AuthenticationHandler<TestAuthenticationOptions>
{
#region Constructors
public TestAuthenticationHandler(IOptionsMonitor<TestAuthenticationOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
{
}
#endregion
#region Public Methods
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var authenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(Options.Identity),
new AuthenticationProperties(),
"Test Scheme");
return Task.FromResult(AuthenticateResult.Success(authenticationTicket));
}
#endregion
}
public static class TestAuthenticationExtensions
{
#region Public Methods
public static AuthenticationBuilder AddTestAuth(this AuthenticationBuilder builder,
Action<TestAuthenticationOptions> configureOptions) =>
builder.AddScheme<TestAuthenticationOptions, TestAuthenticationHandler>("Test Scheme",
"Test Auth",
configureOptions);
#endregion
}
public class TestAuthenticationOptions : AuthenticationSchemeOptions
{
#region Properties
public virtual ClaimsIdentity Identity { get; } = new ClaimsIdentity(new[]
{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
Guid.NewGuid()
.ToString())
},
"test");
#endregion
}
В моем тесте ответ возвращается с кодом Forbidden
, и я не знаю почему. Я явно пытаюсь избежать использования OKTA для проверки подлинности в моих интеграционных тестах, но я не уверен, как «подделать» возврат токена с утверждениями, которые я ожидаю проверить в моих обработчиках / политиках авторизации при обращении к различным контроллерам методы.
Вот мой удар по тесту:
[TestFixture]
public class ClientDataSubmissions
{
private TestServer _testServer;
private HttpClient _client;
[OneTimeSetUp]
public void OneTimeSetUp()
{
var builder = new WebHostBuilder()
.UseStartup<TestStartup>();
_testServer = new TestServer(builder);
_client = _testServer.CreateClient();
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
_client.Dispose();
_testServer.Dispose();
}
[Test]
public async Task Test()
{
var response = await _client.GetAsync("/api/ClientDataSubmission");
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized));
}
}
Как настроить интеграционное тестирование в тестовом веб-интерфейсе API dotnet core, использующем open id connect jwts?