我在 ASP.NET 和 IdentityServer4 项目上有一个 WebAPI,用于授权、注册和所有这些东西。所以,现在我为此 API 创建集成测试,但我无法访问具有 [Authorize] 标记的 API 方法,并且我在测试时遇到 Unauthoruzed:401 异常。 例如 WebAPI 方法:
[ProducesResponseType(typeof(ChangePasswordResponse), 200)]
[ProducesResponseType(typeof(ChangePasswordResponse), 400)]
[Authorize]
[HttpPost("change-password")]
public async Task<ActionResult<ChangePasswordResponse>> ChangePassword([FromBody] ChangePasswordRequest request)
{
_logger.LogInformation("***");
var model = _mapper.Map<ChangePasswordModel>(request);
var response = await _userAccountService.ChangePassword(model);
if (response == null)
return BadRequest(response);
return Ok(response);
}
测试是:
[Fact]
public async Task ChangePassword_Returns200Response()
{
// Arrange;
var model = new ChangePasswordRequest
{
Email = StudentConsts.Email,
CurrentPassword = StudentConsts.Password,
NewPassword = StudentConsts.NewPassword
};
var request = _sutDataHelper.GenerateRequestFromModel(model);
// Act
var response = await _client.PostAsync("accounts/change-password", request);
var responseContent = response.Content.ReadAsStringAsync().Result;
var content = JsonSerializer.Deserialize<ChangePasswordResponse>(responseContent);
// Asserts
response.EnsureSuccessStatusCode();
content.Email.Should().Be(model.Email);
content.UserName.Should().Be(StudentConsts.UserName);
}
集成测试是使用
IClassFixture<CustomWebApplicationFactory>
创建的,我没有从 WebAPI 中放置任何用于身份验证的代码,但是当我从 WebAPI 中放置此代码时,我收到如下错误:SchemeAlreadyExists: Identity.Application
或 SchemeAlreadyExists: Bearer
授权服务设置代码:
services
.AddIdentity<User, IdentityRole<Guid>>(options =>
{
options.Password.RequiredLength = 8;
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddUserManager<UserManager<User>>()
.AddDefaultTokenProviders();
services.AddAuthentication(options =>
{
options.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
})
.AddJwtBearer(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
{
options.RequireHttpsMetadata = "HERE IS IDENTITYSERVER4 SERVICE URL";
options.Authority = "HERE IS IDENTITYSERVER4 SERVICE URL";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = false,
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
options.Audience = "api";
});
services.AddAuthorization(options =>
{
options.AddPolicy(AppScopes.OpenId, policy => policy.RequireClaim("scope", AppScopes.OpenId));
options.AddPolicy(AppScopes.Profile, policy => policy.RequireClaim("scope", AppScopes.Profile));
options.AddPolicy(AppScopes.Email, policy => policy.RequireClaim("scope", AppScopes.Email));
...
});
当我添加另一个 AnotherWebApplicationFactory 文件时,IDE 只是告诉我程序类存在于 WebAPI 和 IS4 项目中,也许这意味着我无法同时创建 2 个项目进行集成测试以从 http://host:00/ 获取 access_token连接/令牌 identityserver4 链接。 此外,我不能只是硬编码来自其他用户的假 access_token,我自己在 WebAPI 中注册,因为他告诉我不允许使用令牌或类似的东西。我刚刚开始学习集成测试并获得授权堆栈。