Дотнет ядро ​​веб-API интеграции тестирования - PullRequest
0 голосов
/ 29 марта 2019

В производстве я использую 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?

...