今天我把WebAPI部署到CentOS Docker容器中運行,發現原有在Windows下允許的JWTBearer配置出現了問題
在Window下我一直使用這個配置,沒有問題
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = _authorityconfig.Authority; options.RequireHttpsMetadata = _authorityconfig.RequireHttpsMetadata; options.Audience = "userservicesapi"; //scope; }) ;
但是到Docker中出現了500服務器內部錯誤,我通過swagger excute看下,已經成功頒發了jwt token了
為什么會出現這個情況呢?
我在docker中通過如下查看日志情況
docker logs --tail 1000 containerid & name
這是錯誤信息
fail: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[3] Exception occurred while processing message. System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'http://192.168.0.212:40000/.well-known/openid-configuration'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'http://192.168.0.212:40000/.well-known/openid-configuration'. ---> System.Net.Http.HttpRequestException: No route to host ---> System.Net.Sockets.SocketException: No route to host at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask`1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask`1.get_Result() at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask) at System.Threading.Tasks.ValueTask`1.get_Result() at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) 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.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
無法獲取到這個配置
http://192.168.0.212:40000/.well-known/openid-configuration
於是我通過
curl http://192.168.0.212:40000/.well-known/openid-configuration
發現是能夠得到的,后來發現原來是因為沒有設置獲取配置的地址的屬性:MetadataAddress
於是我們設置好了最后發布到容器中,發現還是不行,依然有這個錯誤信息,於是我仔細看了下錯誤問題 下面這段:
at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.GetConfigurationAsync(CancellationToken cancel)
這段貌似是需要配置OpenIdConnectConfiguration,沒錯,當時我感覺就是它了,心動異常,所以在代碼里加上了配置
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = _authorityconfig.Authority; options.RequireHttpsMetadata = _authorityconfig.RequireHttpsMetadata; options.Audience = "userservicesapi"; //scope; options.MetadataAddress = _authorityconfig.Authority + "/.well-known/openid-configuration"; options.Configuration = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration(); });
紅色部分為新加入的配置信息,這樣我再次重新打包發布到Docker中,請求雖然沒出現之前的錯誤,然而授權后請求授權保護接口提示簽名錯誤,授權失敗,糾結一段時間之后,我在仔細看了錯誤信息中的如下信息:
Unable to retrieve document from: 'http://192.168.0.212:40000/.well-known/openid-configuration'.
---> System.Net.Http.HttpRequestException: No route to host ---> System.Net.Sockets.SocketException: No route to host
No route to host 這個問題:分析了下原來是因為我雖然是同一個宿主機器,但是我是2個容器,存在容器與容器之間的網絡訪問問題,這里我防火牆開了40000端口后測試就沒有問題了
當然你也可以把兩個容器網絡連在一起
這里就會衍生一個問題:同一個宿主機上的2個容器網絡聯系在一起或 不同宿主機之間的2個容器的網絡聯系在一起的處理,具體不說了~