我正在尝试在项目中设置集成测试,其中应用程序由 AzureAd (Microsoft.Identity.Web) 和 2FA 保护。通常,用户会使用 SPA 登录应用程序,并会看到登录弹出窗口或重定向。在测试控制器端点时,没有 SPA 并且我们没有使用代表流程,因此我认为我可以简单地以通常的方式获取令牌以用于测试目的:
[HttpPost]
public async Task<IActionResult> GetTokenAsync([FromBody] TokenRequest model)
{
_client.BaseAddress = new Uri("https://login.microsoftonline.com/");
var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
/* ... */
}
var response = await _client.PostAsync($"{_options.TenantId}/oauth2/v2.0/token", content);
var responseContent = await response.Content.ReadAsStringAsync();
var token = JsonConvert.DeserializeObject<dynamic>(responseContent);
return Ok(new TokenResponse { Token = token.id_token });
}
但是,由于启用了 2FA,我收到以下错误:
{{
"error": "invalid_grant",
"error_description": "AADSTS50158: External security challenge not satisfied. User will be redirected to another page or authentication provider to satisfy additional authentication
"error_codes": [
50158
],
"timestamp": "2020-12-04 12:41:10Z",
"trace_id": "xxxxxxxxxxxxxx",
"correlation_id": "xxxxxxxxxxxxxxxxxxx",
"error_uri": "https://login.microsoftonline.com/error?code=50158",
"suberror": "basic_action",
"claims": "{ /* ... */}"
}}
更易于阅读的版本:https://login.microsoftonline.com/error?code=50158
以下是身份验证配置的相关部分:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddMicrosoftIdentityWebApi(this.Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(this.Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
/* ... */
}
有没有办法在测试期间满足或规避 2FA 要求,同时保持基本代币机制完整?
更新 为了消除任何可能的混乱:我的目标是自动化测试,无需人工干预。我知道,我可以使用带有自定义
WebApplicationFactory
的模拟身份验证方案,但如果可能的话,我会采用不太假的方法。
围绕 MFA 实现自动化很困难,因为它是专门为避免除实时人机交互之外的任何东西而设计的。鉴于任何解决方法都可能打开攻击媒介,因此自动化替代方案只能在开发和测试环境中公开和配置。
当我们在 Azure 应用程序中切换到 MFA 时,我将面临类似的挑战。根据我的经验,自动化单元测试,尤其是那些为 CI/CD 构建通过/失败设置条件的测试,需要能够绕过某些实时集成点并仅测试目标代码路径。这种设计要求的一个支柱是在必要时通过重构来“支持组合而不是继承”。不要让您的代码(Microsoft.Identity、Kiota 和 Graph)执行需要用户交互的完整身份验证,而是拥有一个允许 MFA 内容的不同委托的属性,并让集成测试安全地用模拟或其他安全的方法替换该委托选择。如果 WebApplicationFactory 距离其他 Azure 资源要求太远,则必须在测试环境中启用某些备用身份验证方法。该线程可能会为您指明正确的方向:https://stackoverflow.com/a/41735856/888792