Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 如何配置ASP.NETTestHost以使用OpenIDConnect?_Asp.net Core_Openid Connect_Identityserver4_Asp.net Core Testhost - Fatal编程技术网

Asp.net core 如何配置ASP.NETTestHost以使用OpenIDConnect?

Asp.net core 如何配置ASP.NETTestHost以使用OpenIDConnect?,asp.net-core,openid-connect,identityserver4,asp.net-core-testhost,Asp.net Core,Openid Connect,Identityserver4,Asp.net Core Testhost,我有一个ASP.Net核心应用程序,配置为发布和验证JWT承载令牌。当站点托管在Kestrel中时,客户端能够成功检索承载令牌并使用令牌进行身份验证 我还有一套使用Microsoft.AspNetCore.TestHost.TestServer的集成测试。在添加身份验证之前,测试能够成功地对应用程序发出请求。添加身份验证后,我开始出现与访问开放id配置有关的错误。我看到的具体例外是: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]

我有一个ASP.Net核心应用程序,配置为发布和验证JWT承载令牌。当站点托管在Kestrel中时,客户端能够成功检索承载令牌并使用令牌进行身份验证

我还有一套使用Microsoft.AspNetCore.TestHost.TestServer的集成测试。在添加身份验证之前,测试能够成功地对应用程序发出请求。添加身份验证后,我开始出现与访问开放id配置有关的错误。我看到的具体例外是:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://  
fail: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[3]
      Exception occurred while processing message.
System.InvalidOperationException: IDX10803: Unable to obtain configuration from: 'http://localhost/.well-known/openid-configuration'. ---> System.IO.IOException: IDX10804: Unable to retrieve document from: 'http://localhost/.well-known/openid-configuration'. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 404 (Not Found).
根据我的研究,当权限设置为与托管服务器不同的主机时,有时会触发这种情况。例如,Kestrel在默认情况下运行,这是我最初将权限设置为的,但在将其设置为TestServer正在模拟的()时,它仍然会给出相同的错误。以下是我的身份验证配置:

    app.UseJwtBearerAuthentication(new JwtBearerOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        RequireHttpsMetadata = false,
        TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = signingKey,
            ValidateAudience = true
        },
        Audience = "Anything",
        Authority = "http://localhost"
    });
奇怪的是,尝试从集成测试直接命中URL效果很好:

那么,如何配置ASP.NETTestServer和OpenIDConnect基础架构以协同工作呢

==编辑====


在反思这一点时,我突然意识到问题在于JWT授权内部正在尝试向端口80发出请求,但它没有尝试使用TestServer发出请求,因此正在寻找一个真正的服务器。因为没有,所以它永远不会进行身份验证。看起来下一步是查看是否有某种方法关闭权限检查或以某种方式扩展基础结构,以允许它使用TestServer作为主机。

JWT基础结构确实在默认情况下尝试发出HTTP请求。通过将JWTBeareOptions.ConfigurationManager属性设置为OpenIDConnectionConfiguration Retriever()的新实例,我可以使其正常工作,OpenIDConnectionConfiguration Retriever()提供了DI提供的IDocumentResolver:

        ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
            authority + "/.well-known/openid-configuration",
            new OpenIdConnectConfigurationRetriever(),
            _documentRetriever),
ConfigurationManager=新建ConfigurationManager(
权限+“/.众所周知的/openid配置”,
新的OpenIdConnectConfigurationRetriever(),
_文档检索器),
在生产代码中,我只是将默认值注册到我的容器(Autofac):

builder.RegisterType().As();
我已经为我的集成测试使用了一个派生的安装类,该类遵循模板方法模式来配置容器,因此我能够用一个从TestServer实例返回结果的实例覆盖IDocumentRetriever实例

我确实遇到了另一个障碍,即当发出一个请求(由JWT调用我的IDocumentRetriever启动的请求)时,TestServer的客户端似乎挂起,而另一个请求已经未完成(启动该请求的请求开始),因此,我必须提前发出请求,并从我的IDocumentRetriever提供缓存结果:

public class TestServerDocumentRetriever : IDocumentRetriever
{
    readonly IOpenIdConfigurationAccessor _openIdConfigurationAccessor;

    public TestServerDocumentRetriever(IOpenIdConfigurationAccessor openIdConfigurationAccessor)
    {
        _openIdConfigurationAccessor = openIdConfigurationAccessor;
    }

    public Task<string> GetDocumentAsync(string address, CancellationToken cancel)
    {
        return Task.FromResult(_openIdConfigurationAccessor.GetOpenIdConfiguration());
    }
}
公共类TestServerDocumentRetriever:IDocumentRetriever
{
只读IOpenidConfiguration访问器\u openIdConfigurationAccessor;
公共TestServerDocumentRetriever(IOpenidConfiguration访问器openIdConfigurationAccessor)
{
_openIdConfigurationAccessor=openIdConfigurationAccessor;
}
公共任务GetDocumentAsync(字符串地址,取消令牌取消)
{
返回Task.FromResult(_openIdConfigurationAccessor.GetOpenIdConfiguration());
}
}

您的编辑是正确的。您是否尝试过在测试中提供不设置权限的配置?从技术上讲,您的测试应该需要的是一个经过身份验证的用户,您可以临时制作/模拟这个用户,而不必使用JWT身份验证。我相信我尝试过不设置权限,但我似乎记得它抛出了一个错误。我最终找到了一个解决方案,并将发布一个答案。您好@Derek,我希望您不介意我为其他使用IdentityServer4的人劫持此线程,并尝试进行集成测试。我在这个线程中找到了解决方案
public class TestServerDocumentRetriever : IDocumentRetriever
{
    readonly IOpenIdConfigurationAccessor _openIdConfigurationAccessor;

    public TestServerDocumentRetriever(IOpenIdConfigurationAccessor openIdConfigurationAccessor)
    {
        _openIdConfigurationAccessor = openIdConfigurationAccessor;
    }

    public Task<string> GetDocumentAsync(string address, CancellationToken cancel)
    {
        return Task.FromResult(_openIdConfigurationAccessor.GetOpenIdConfiguration());
    }
}