【问题标题】:Mock JwtBearerOptions BackendChannel for integration tests模拟 JwtBearerOptions BackendChannel 用于集成测试
【发布时间】:2022-07-12 21:34:27
【问题描述】:

在我的应用中,我使用以下代码添加:

authBuilder
    .AddJwtBearer("MyCustomScheme", options =>
    {
        options.Authority = "https://auth.example.com";
        options.AutomaticRefreshInterval = new TimeSpan(24, 0, 0);
    });

在我的集成测试项目中,我有以下代码:

public class TestAppFactory : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        // tried also with .ConfigureTestServices
        builder.ConfigureServices(services =>
        {
            services.PostConfigure<JwtBearerOptions>("MyCustomScheme", options =>
            {
                // this is executed and options.Authority is auth.example.com here

                options.MetadataAddress = "https://inmemory.microsoft.com/common/.well-known/openid-configuration";
                options.Authority = "https://inmemory.microsoft.com/common/.well-known/openid-configuration";
                options.BackchannelHttpHandler = new MockBackchannel();
            });
        });
    }
}

而 MockBackendChannel 看起来像这样:

public class MockBackchannel : HttpMessageHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.RequestUri.AbsoluteUri.Equals("https://inmemory.microsoft.com/common/.well-known/openid-configuration"))
        {
            return await EmbeddedResourceReader.GetOpenIdConfigurationAsResponseMessage("microsoft-openid-config.json");
        }
        if (request.RequestUri.AbsoluteUri.Equals("https://inmemory.microsoft.com/common/discovery/keys"))
        {
            return await EmbeddedResourceReader.GetOpenIdConfigurationAsResponseMessage("microsoft-wellknown-keys.json");
        }

        throw new NotImplementedException();
    }
}

我检查了services.PostConfigure&lt;JwtBearerOptions&gt; 是否在应用程序中设置的选项上正确调用,但是当我在集成测试中调用授权 API 时(使用Application.CreateClient() 创建的客户端)我收到以下异常:

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'System.String'.
 ---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'System.String'.
 ---> System.Net.Http.HttpRequestException: nodename nor servname provided, or not known (auth.example.com:443)
 ---> System.Net.Sockets.SocketException (0xFFFDFFFF): nodename nor servname provided, or not known

所以由于某种原因后配置对方案没有影响,它仍在尝试调用 auth.example.com。我怎样才能做到这一点?

【问题讨论】:

    标签: .net-core


    【解决方案1】:

    您好像在关注same tutorial as me

    从我在aspnet's source code 中看到的内容来看,有一个 PostConfiguration 应该采用反向通道并从中创建一个客户端。我的猜测是我们的 PostConfiguration 在那个之后运行,所以客户端从不使用我们的反向通道。

    解决我的问题的解决方法是将代码从 PostConfigure 复制粘贴到我的 PostConfigure 中,以便我们初始化整个客户端:

    services.PostConfigure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
    {
        options.BackchannelHttpHandler = new MockBackchannel();
        options.Backchannel = new HttpClient(options.BackchannelHttpHandler);
        options.Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core JwtBearer handler");
        options.Backchannel.Timeout = options.BackchannelTimeout;
        options.Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB
        options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(options.MetadataAddress, new OpenIdConnectConfigurationRetriever(),
            new HttpDocumentRetriever(options.Backchannel) { RequireHttps = options.RequireHttpsMetadata })
        {
            RefreshInterval = options.RefreshInterval,
            AutomaticRefreshInterval = options.AutomaticRefreshInterval,
        };
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-25
      • 2011-03-15
      • 2017-01-23
      • 1970-01-01
      • 2020-12-16
      • 2019-07-20
      • 1970-01-01
      • 2021-07-05
      相关资源
      最近更新 更多