在生产中,我使用OKTA进行身份验证和授权(开放ID连接)。我一直在努力写出集成测试。
在我的测试项目中,我有一个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));
}
}
如何在使用开放ID Connect jwts的dotnet核心Web API测试项目中设置集成测试?