- identityserver4 - 使用内存IdentityServer进行集成测试

  显示原文与译文双语对照的内容

我有一个使用IdentityServer4进行令牌验证的API 。 我想用一个内存TestServer这个 API 。 我想在内存中托管 IdentityServer 。

我已经从IdentityServer中创建了一个令牌。

这是我到达的距离,但是我得到了一个错误"无法获得 http://localhost:54100/.well-known/openid-configuration from的配置"

Api使用了不同策略的[Authorize] -attribute 。 这就是我想测试的。

我可以这样做我在做什么? 我试图查看IdentityServer4的源代码,但是没有过于类似的集成测试方案。


protected IntegrationTestBase()


{


 var startupAssembly = typeof(Startup).GetTypeInfo().Assembly;



 _contentRoot = SolutionPathUtility.GetProjectPath(@"<my project path>", startupAssembly);


 Configure(_contentRoot);


 var orderApiServerBuilder = new WebHostBuilder()


. UseContentRoot(_contentRoot)


. ConfigureServices(InitializeServices)


. UseStartup<Startup>();


 orderApiServerBuilder.Configure(ConfigureApp);


 OrderApiTestServer = new TestServer(orderApiServerBuilder);



 HttpClient = OrderApiTestServer.CreateClient();


}



private void InitializeServices(IServiceCollection services)


{


 var cert = new X509Certificate2(Path.Combine(_contentRoot,"idsvr3test.pfx"),"idsrv3test");


 services.AddIdentityServer(options =>


 {


 options.IssuerUri ="http://localhost:54100";


 })


. AddInMemoryClients(Clients.Get())


. AddInMemoryScopes(Scopes.Get())


. AddInMemoryUsers(Users.Get())


. SetSigningCredential(cert);



 services.AddAuthorization(options =>


 {


 options.AddPolicy(OrderApiConstants.StoreIdPolicyName, policy => policy.Requirements.Add(new StoreIdRequirement("storeId")));


 });


 services.AddSingleton<IPersistedGrantStore, InMemoryPersistedGrantStore>();


 services.AddSingleton(_orderManagerMock.Object);


 services.AddMvc();


}



private void ConfigureApp(IApplicationBuilder app)


{


 app.UseIdentityServer();


 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();


 var options = new IdentityServerAuthenticationOptions


 {


 Authority = _appsettings.IdentityServerAddress,


 RequireHttpsMetadata = false,



 ScopeName = _appsettings.IdentityServerScopeName,


 AutomaticAuthenticate = false


 };


 app.UseIdentityServerAuthentication(options);


 app.UseMvc();


}



在我的单元测试中:


private HttpMessageHandler _handler;


const string TokenEndpoint ="http://localhost/connect/token";


public Test()


{


 _handler = OrderApiTestServer.CreateHandler();


}



[Fact]


public async Task LeTest()


{


 var accessToken = await GetToken();


 HttpClient.SetBearerToken(accessToken);



 var httpResponseMessage = await HttpClient.GetAsync("stores/11/orders/asdf");//Fails on this line



}



private async Task<string> GetToken()


{


 var client = new TokenClient(TokenEndpoint,"client","secret", innerHttpMessageHandler: _handler);



 var response = await client.RequestClientCredentialsAsync("TheMOON.OrderApi");



 return response.AccessToken;


}



时间:

我想你可能需要为你的授权中间件做一个双重测试,这取决于你想要多少功能。 所以基本上,你需要一个中间件来执行授权中间件减去对发现文档的后退通道调用。

IdentityServer4.AccessTokenValidation 是两个中间件的封装器。 JwtBearerAuthentication 中间件和 OAuth2IntrospectionAuthentication 中间件。 这两种方法都通过http获取发现文档,用于令牌验证。 如果你想做一个内存自包含测试,那就是一个问题。

如果你想要解决这个问题,你可以能需要做一个假版本。 app.UseIdentityServerAuthentication 这不执行获取发现文档的外部调用。 它只填充HttpContext主体,以便可以测试你的[Authorize] 策略。

看看 IdentityServer4.AccessTokenValidation的肉是如何在这里看到的。 接下来,看看JwtBearer中间件在这里是如何看起来像的。

...