首页 > 解决方案 > 实现 Docker 和 Nginx 时遇到的问题

问题描述

我故意删除了代码和图像中的敏感信息

我在设置使用Dockerand时遇到了几个问题Nginx。我的解决方案/服务已成功对接,但服务无法通过Nginx.

我有一个 docker,其中包含 3 个服务,这是我的解决方案。

还要注意Nginx的是我的 Docker 中的一项服务。我的所有服务端口都正确暴露

设置详情如下:

问题 1用户已成功登录 viaAuth Service并将Auth Service重定向到我的Portal Servicevia Nginx。但相反,我遇到了一个问题,Portal Service即无法获取Auth Service's Discovery EndPoint。

还要注意 Auth Service;一旦用户登录成功,服务将生成两个cookies;idsrv.sessionan external .net cookies在 IIS 中,这两个 cookie 将在整个服务中共享。Portal Service 需要 Auth Service 的元数据才能生成 JWT cookie。

错误截图

错误日志:

Request starting HTTP/1.1 GET http://app-local..com:44343/favicon.ico - -

Executing endpoint '..Web.Controllers.ErrorController.Route (..Web)'

Route matched with {action = "Route", controller = "Error"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.IActionResult Route(System.String) on controller ..Web.Controllers.ErrorController (..Web).

Authorization failed. These requirements were not met:
DenyAnonymousAuthorizationRequirement: Requires an authenticated user.

[INF]  Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.

[INF]  Executing ChallengeResult with authentication schemes ([]).

[INF]  Executed action ..Web.Controllers.ErrorController.Route (.Web) in 3.2872ms

[INF]  Executed endpoint '..Web.Controllers.ErrorController.Route (.Web)'

[ERR]  An unhandled exception has occurred while executing the request.System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://id-local..com:5200/.well-known/openid-configuration'.
  ---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://id-local..com:5200/.well-known/openid-configuration'.
  ---> System.Net.Http.HttpRequestException: Connection refused (id-local..com:5200)
  ---> System.Net.Sockets.SocketException (111): Connection refused
    at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
    at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
    at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|283_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
    at System.Net.Http.HttpConnectionPool.DefaultConnectAsync(SocketsHttpConnectionContext context, CancellationToken cancellationToken)
    at System.Net.Http.ConnectHelper.ConnectAsync(Func`3 callback, DnsEndPoint endPoint, HttpRequestMessage requestMessage, CancellationToken cancellationToken)
    --- End of inner exception stack trace ---
    at System.Net.Http.ConnectHelper.ConnectAsync(Func`3 callback, DnsEndPoint endPoint, HttpRequestMessage requestMessage, CancellationToken cancellationToken)
    at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
    at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
    at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
    at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
    at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
    at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
    at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
    at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
    --- End of inner exception stack trace ---
    at Microsoft.IdentityModel.Protocols.HttpDocumentRetriever.GetDocumentAsync(String address, CancellationToken cancel)
    at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel)
    at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
    --- End of inner exception stack trace ---
    at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
    at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsyncInternal(AuthenticationProperties properties)
    at Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler.HandleChallengeAsync(AuthenticationProperties properties)
    at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.ChallengeAsync(AuthenticationProperties properties)
    at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
    at Microsoft.AspNetCore.Mvc.ChallengeResult.ExecuteResultAsync(ActionContext context)
    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAlwaysRunResultFilters>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
    at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
    at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
    at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
    at WebMarkupMin.AspNetCore3.WebMarkupMinMiddleware.ProcessAsync(HttpContext context, Boolean useMinification, Boolean useCompression)
    at WebMarkupMin.AspNetCore3.WebMarkupMinMiddleware.ProcessAsync(HttpContext context, Boolean useMinification, Boolean useCompression)
    at WebMarkupMin.AspNetCore3.WebMarkupMinMiddlewareBase.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Builder.StatusCodePagesExtensions.<>c__DisplayClass6_0.<<UseStatusCodePagesWithReExecute>b__0>d.MoveNext()
 --- End of stack trace from previous location ---
    at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)366
[INF]  Request finished HTTP/1.1 GET http://app-local..com:44343/favicon.ico - - - 500 - text/plain 8.9ms

部分Nginx配置文件

upstream auth 
{
    server authservice:5001;
}
upstream portal
{ 
    server portalservice:5010;
}

server 
{        
    listen 44343 http2 ssl;

    server_name id-local.com;    

    location /
    {
        proxy_pass         http://auth;
        proxy_redirect     off;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host:44343;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   X-Forwarded-Host $server_name;
    }
}

server 
{        
    listen 44343 http2 ssl;

    server_name app-local.com;    

    location /
    {
        proxy_pass         http://portal;
        proxy_redirect     off;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host:44343;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   X-Forwarded-Host $server_name:44343;
        proxy_buffer_size           128k;
        proxy_buffers               4 256k;
        proxy_busy_buffers_size     256k;
    }
}

问题 2我尝试Nginx用作API Service. 并遇到另一个问题。

错误日志

"GET /api/v1 HTTP/2.0" 502 559 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
[error] 34#34: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 123.456.112.1, server: app-local..com, request: "GET /api/v1 HTTP/2.0", upstream: "http://123.456.112.6:5020/api/v1", host: "app-local.com:5200"

部分Nginx配置文件

upstream api 
{ 
    server apiservice:5020;
}
server 
{        
    listen 44343 http2 ssl;

    server_name app-local.com;    
    #include /etc/nginx/default.d/*.conf;
            
    location /api/v1
    {
         proxy_pass         http://api/api/v1;
         proxy_redirect     off;
         proxy_http_version 1.1;
         proxy_cache_bypass $http_upgrade;
         proxy_set_header   Upgrade $http_upgrade;
         proxy_set_header   Connection keep-alive;
         proxy_set_header   Host $host:44343;
         proxy_set_header   X-Real-IP $remote_addr;
         proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header   X-Forwarded-Proto $scheme;
         proxy_set_header   X-Forwarded-Host $server_name:44343;
         proxy_buffer_size           128k;
         proxy_buffers               4 256k;
         proxy_busy_buffers_size     256k;
     }
 }

从错误来看,似乎Nginx无法访问API Service's 容器。令人费解的是什么;使用 Postman 时,我可以通过http://localhost:5020/api/v1.

部分docker-compose.yml

version: '3.9'

    services:
      nginxservice:
        build:
          context: .
          dockerfile: 
        depends_on:
          - authservice
        ports:
          - "5200:44343"

      apiservice:
        image: ${DOCKER_REGISTRY-}
        build:
          context: .
          dockerfile: 
        environment:
          - ASPNETCORE_ENVIRONMENT=Development
          - ASPNETCORE_URLS=http://+:80
        ports:
          - 5020:80

    portalservice:
    image: ${DOCKER_REGISTRY-}
    build:
      context: .
      dockerfile: 
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://*:5010
    ports:
      - 5010:5010

  authservice:
    image: ${DOCKER_REGISTRY-}
    build:
      context: .
      dockerfile: 
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://*:5001
    restart: always
    ports:
      - 5001:5001

感谢大家的帮助

*编辑:2021 年 7 月 14 日:添加更多详细信息,尤其是有关服务设置和服务器名称的信息。

标签: asp.net-mvcdockernginxopenid-connect

解决方案


有几件事引起了我的注意。

  • 您是否打算使用 SSL?您是否在将 SSL 证书/密钥配置放在这里时忽略了它?无论哪种方式,http://app-local..com:44343似乎都与您id-local通过 https 访问的图像中的端点相矛盾。
  • 您似乎已配置id-local.com为侦听 port 44343。您是否在您的 oidc 客户端应用程序中正确配置它?(无法从屏幕截图中真正看到,因为 URL 的某些部分是隐藏的)
  • 您似乎表明用户已成功登录。我假设这涉及到一个 cookie。您能否检查是否为正确的域设置了 cookie,因此对您的身份验证服务的后续请求实际上是否收到了 cookie?

推荐阅读