背景

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

https required.png

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"
    }
  }

标签: HTTPS required, well-known/openid-configuration, SSL connection could not be established, RemoteService

添加新评论