如何获得access_token集成测试通过[授权]标签?ASP.净之前



我在ASP上有一个WebAPI。. NET和IdentityServer4项目的授权,注册和所有这些东西。所以,现在我正在为这个API创建集成测试,我无法访问具有[Authorize]标记的API方法,并且我在测试上得到未授权: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.ApplicationSchemeAlreadyExists: 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/connect/token identityserver4链接获取access_token的集成测试。我也不能硬编码假access_token从其他用户我自己注册在WebAPI,因为他告诉我,令牌不允许或类似的东西。我刚开始学习集成测试和获得堆栈授权。

解决方法:https://question-it.com/questions/418799/kak-otkljuchit-vkljuchit-autentifikatsiju-vo-vremja-vypolnenija-v-aspnet-core-22

使用AuthRequirement和AuthRequirementHandler在集成测试中明确地为服务设置添加了策略。

服务设置:

services.AddScoped<IAuthorizationHandler, MaintenanceModeDisabledOrAuthenticatedUserRequirementHandler>();
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder()
.AddRequirements(new MaintenanceModeDisabledOrAuthenticatedUserRequirement())
.Build();
options.AddPolicy(AppScopes.OpenId, builder => builder
.AddRequirements(new MaintenanceModeDisabledOrAuthenticatedUserRequirement()));
options.AddPolicy(AppScopes.Profile, builder => builder
.AddRequirements(new MaintenanceModeDisabledOrAuthenticatedUserRequirement()));
options.AddPolicy(AppScopes.Email, builder => builder
.AddRequirements(new MaintenanceModeDisabledOrAuthenticatedUserRequirement()));
});

AuthRequirement:

public class MaintenanceModeDisabledOrAuthenticatedUserRequirement : IAuthorizationRequirement
{ }

AuthRequirementHandler:

public class MaintenanceModeDisabledOrAuthenticatedUserRequirementHandler : AuthorizationHandler<MaintenanceModeDisabledOrAuthenticatedUserRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MaintenanceModeDisabledOrAuthenticatedUserRequirement requirement)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}

希望你解决了你的问题!

相关内容

  • 没有找到相关文章

最新更新