asp.net-mvc - 实现 Docker 和 Nginx 时遇到的问题
问题描述
我故意删除了代码和图像中的敏感信息
我在设置使用Docker
and时遇到了几个问题Nginx
。我的解决方案/服务已成功对接,但服务无法通过Nginx
.
我有一个 docker,其中包含 3 个服务,这是我的解决方案。
Auth Service
; 使用 OpenID Connect 登录时向身份验证用户Portal Service
; 经过身份验证的用户可以访问各种视图API Service
; 根据用户请求获取或发布的 API。
还要注意Nginx
的是我的 Docker 中的一项服务。我的所有服务端口都正确暴露
设置详情如下:
Auth Service
位于服务器名称为 id-local..com 的反向代理中Portal Service
位于服务器名称为 app-local..com 的反向代理中API Service
是一个 API 网关,与 Portal Service 共享相同的服务器名称;应用程序本地..com- 两台服务器都使用 SSL 和 HTTP2 运行;我省略了与 SSL 相关的 cert。
- 两台服务器实际上是相同的 IP 地址,因为它们位于同一台 PC 上。请注意,
Nginx
我正在学习教程中的端口号可能是错误的。
问题 1用户已成功登录 viaAuth Service
并将Auth Service
重定向到我的Portal Service
via Nginx
。但相反,我遇到了一个问题,Portal Service
即无法获取Auth Service
's Discovery EndPoint。
还要注意 Auth Service;一旦用户登录成功,服务将生成两个cookies;idsrv.session
和an 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 日:添加更多详细信息,尤其是有关服务设置和服务器名称的信息。
解决方案
有几件事引起了我的注意。
- 您是否打算使用 SSL?您是否在将 SSL 证书/密钥配置放在这里时忽略了它?无论哪种方式,
http://app-local..com:44343
似乎都与您id-local
通过 https 访问的图像中的端点相矛盾。 - 您似乎已配置
id-local.com
为侦听 port44343
。您是否在您的 oidc 客户端应用程序中正确配置它?(无法从屏幕截图中真正看到,因为 URL 的某些部分是隐藏的) - 您似乎表明用户已成功登录。我假设这涉及到一个 cookie。您能否检查是否为正确的域设置了 cookie,因此对您的身份验证服务的后续请求实际上是否收到了 cookie?
推荐阅读
- kotlin - 如何正确抛出 IllegalArgumentException?
- keras - Model.evaluate 在具有多输入和多输出的 keras 中
- python - 使用请求库的 Python-3 Minecraft UUID 到用户名
- r - 是否有任何包或方法可以将 data.table R 代码转换/发送为 sql 查询以发送到数据库?
- html - 如何为我的复选框赋予背景颜色?
- java - Can one JDBC Statement be used at the same time?
- c++ - Increment an integer pointer and assign the value of the incremented pointer to another variable in C++
- sqlite - How do I fix an exception thrown during unit testing because SQLite doesn't have a certain function defined in HasDefaultValueSql?
- python - Will Anaconda work well if it is not the system python?
- javascript - ECMAScript AssignmentExpression 生产规则如何产生`foo = 42`?