背景
使用abp vNext框架进行微服务开发时,使用了其中的Remote Service功能,本地调试没有任何问题,但是在部署到服务器时,在请求使用了远程服务调用的接口时,出现了如下错误提示。

ERR] Could not retrieve the OpenId Connect discovery document! ErrorType: Exception. Error: Error connecting to http://10.0.0.101:5001/.well-known/openid-configuration. HTTPS required.
2020-10-21T02:40:36.618868530Z Volo.Abp.AbpException: Could not retrieve the OpenId Connect discovery document! ErrorType: Exception. Error: Error connecting to http://10.0.0.101:5001/.well-known/openid-configuration. HTTPS required.
2020-10-21T02:40:36.618916073Z at Volo.Abp.IdentityModel.IdentityModelAuthenticationService.GetTokenEndpoint(IdentityClientConfiguration configuration)
2020-10-21T02:40:36.618928596Z at Volo.Abp.IdentityModel.IdentityModelAuthenticationService.GetTokenResponse(IdentityClientConfiguration configuration)
...
很明显是ids4的该请求需要https方式,但是很多时候,该服务是内网环境调用,没必要https,二期内网环境调试也不方便。
但是我检查了配置,发现已经在模块初始化时,配置了 options.RequireHttpsMetadata = false;
,而且一些需要认证的接口添加了[Authorize]
,也是可以正常使用的。
问题分析
也就是说,目前的情况,只有在远程服务调用时,才会出现。而该问题明显是在获取Identity Server4信息时出的错误。这样我们可以推断出,我们的模块中ConfigureServices配置的options.RequireHttpsMetadata = false;
并不会对应用层调用远程服务生效。
我前去查看了abp 源码,找到了IdentityModelAuthenticationService类,关键代码如下:
protected virtual async Task<DiscoveryDocumentResponse> GetDiscoveryResponse(IdentityClientConfiguration configuration)
{
using (var httpClient = HttpClientFactory.CreateClient(HttpClientName))
{
var request = new DiscoveryDocumentRequest
{
Address = configuration.Authority,
Policy =
{
RequireHttps = configuration.RequireHttps
}
};
IdentityModelHttpRequestMessageOptions.ConfigureHttpRequestMessage?.Invoke(request);
return await httpClient.GetDiscoveryDocumentAsync(request);
}
}
这样,一下子就明了了,我们在appsettings.json
配置文件中,有两个认证服务的配置:
"AuthServer": {
"Authority": "http://x.x.x.x:5001",
"ApiName": "IdentityService"
},
"IdentityClients": {
"Default": {
"GrantType": "client_credentials",
"ClientId": "xxx-app",
"ClientSecret": "1q2w3e*",
"Authority": "http://x.x.x.x:5001",
"Scope": "IdentityService InternalGateway xxx"
}
第一个就是对应到了,上面提到的模块初始化时的AddAuthentication
配置(当然你要是直接在源码中写死了,可能没有这一项),另一个才是对远程服务调用时起作用的配置内容。
解决
问题找到了就好办了,根据IdentityClientConfiguration
的结构,我们很容易猜出来,应该在IdentityClients
配置中添加一项RequireHttps
的item,并设置为false。修改后如下:
"IdentityClients": {
"Default": {
"GrantType": "client_credentials",
"ClientId": "xxx-app",
"ClientSecret": "1q2w3e*",
"RequireHttps": false,
"Authority": "http://x.x.x.x:5001",
"Scope": "IdentityService InternalGateway xxx"
}
}