【问题标题】:How to host BOT Framework V4 BOT on IIS如何在 IIS 上托管 BOT Framework V4 BOT
【发布时间】:2019-06-04 23:53:27
【问题描述】:

我在 IIS 上托管我的 BOT Framework V4 BOT。 服务器配置如下

  1. Windows Server 2012 R2
  2. IIS 8.5

我还安装了 dotnet-hosting-2.2.1-win.exe,这是托管 BOT V4 所必需的。我已将应用程序池设置为无托管代码。 我已经设置了 Startup.cs 文件所在文件夹的路径。 另外请找到BOT生成的日志的附件。 尽管如此,它仍然无法正常工作,错误如下

HTTP 错误 403.14 - 禁止 Web 服务器配置为不列出此目录的内容。

Detailed Error Information:
Module     DirectoryListingModule
Notification       ExecuteRequestHandler
Handler    StaticFile
Error Code     0x00000000
Requested URL      https://myServer/ConfRoomBOT/
Physical Path      ProjectPath
Logon Method       Anonymous
Logon User     Anonymous
Request Tracing Directory      C:\inetpub\logs\FailedReqLogFiles

下面是web.config代码

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\ConfRoom.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
    </system.webServer>
  </location>
  <system.net>
     <defaultProxy useDefaultCredentials="false">
        <proxy usesystemdefault="False" proxyaddress="http://xx.xxx.xx.xxx:8080" bypassonlocal="True" />
      </defaultProxy>
  </system.net>
</configuration>

以下是BOT生成的日志

托管环境:生产内容根路径: E:\Project\DotNetCoreApps\ConfRoomPub\WithPII\publish 现在收听 on:http://127.0.0.1:41826 应用程序已启动。按 Ctrl+C 关闭 下。信息:Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 请求开始 HTTP/1.1 GET http://example.com/ConfRoom/ info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 请求开始 HTTP/1.1 GET http://example.com/ConfRoom/ info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2] 发送文件。请求路径:'/default.htm'。物理路径:'E:\Project\DotNetCoreApps\ConfRoomPub\WithPII\publish\wwwroot\default.htm' 信息:Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6] 文件 /default.htm 未修改信息:Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 请求在 184.4402 毫秒内完成 304 文本/html 信息:Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 请求在 188.1919 毫秒内完成 200 文本/html 信息:Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 请求开始 HTTP/1.1 POST http://example.com/ConfRoom/api/messages application/json; 字符集=utf-8 373 信息: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 请求开始 HTTP/1.1 POST http://example.com/ConfRoom/api/messages application/json; charset=utf-8 359 失败:Microsoft.AspNetCore.Server.Kestrel[13] 连接 ID“0HLJNNKCOIPS7”,请求 ID“0HLJNNKCOIPS7:00000002”:未处理的异常被抛出 应用。 System.InvalidOperationException:IDX20803:无法 从以下位置获取配置: 'https://login.botframework.com/v1/.well-known/openidconfiguration'。 ---> System.IO.IOException:IDX20804:无法从以下位置检索文档: 'https://login.botframework.com/v1/.well-known/openidconfiguration'。 ---> System.Net.Http.HttpRequestException:连接尝试失败,因为连接方在一段时间后没有正确响应 时间,或建立连接失败,因为连接的主机有 没有回应 ---> System.Net.Sockets.SocketException:连接尝试失败,因为连接方在一段时间后没有正确响应 时间,或建立连接失败,因为连接的主机有 未能回应 System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32 端口, CancellationToken cancelToken) --- 内部异常结束 堆栈跟踪 --- 在 System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,Int32 端口, CancellationToken 取消令牌)在 System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result() 在 System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.get_Result()
在 System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancelToken)
在 System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage 请求,CancellationToken 取消令牌)在 System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task1 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.ConfigurationManager1.GetConfigurationAsync(CancellationToken 取消)---内部异常堆栈跟踪结束---在 Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync(CancellationToken cancel) at Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync() 在 Microsoft.Bot.Connector.Authentication.JwtTokenExtractor.ValidateTokenAsync(字符串 jwtToken, 字符串 channelId) 在 Microsoft.Bot.Connector.Authentication.JwtTokenExtractor.GetIdentityAsync(字符串 方案,字符串参数,字符串channelId)在 Microsoft.Bot.Connector.Authentication.JwtTokenExtractor.GetIdentityAsync(字符串 授权标头,字符串 channelId)在 Microsoft.Bot.Connector.Authentication.ChannelValidation.AuthenticateChannelToken(字符串 authHeader、ICredentialProvider 凭据、HttpClient httpClient、 字符串 channelId) 在 Microsoft.Bot.Connector.Authentication.ChannelValidation.AuthenticateChannelToken(字符串 authHeader、ICredentialProvider 凭据、字符串 serviceUrl、 HttpClient httpClient, String channelId) 在 Microsoft.Bot.Connector.Authentication.JwtTokenValidation.ValidateAuthHeader(字符串 authHeader、ICredentialProvider 凭据、IChannelProvider channelProvider,字符串 channelId,字符串 serviceUrl,HttpClient httpClient) 在 Microsoft.Bot.Connector.Authentication.JwtTokenValidation.AuthenticateRequest(IActivity 活动,字符串 authHeader,ICredentialProvider 凭据, IChannelProvider 提供程序,HttpClient httpClient) 在 Microsoft.Bot.Builder.BotFrameworkAdapter.ProcessActivityAsync(字符串 authHeader、Activity 活动、BotCallbackHandler 回调、 CancellationToken 取消令牌)在 Microsoft.Bot.Builder.Integration.AspNet.Core.Handlers.BotMessageHandler.ProcessMessageRequestAsync(HttpRequest 请求,IAdapterIntegration 适配器,BotCallbackHandler botCallbackHandler, CancellationToken cancelToken) 在 Microsoft.Bot.Builder.Integration.AspNet.Core.Handlers.BotMessageHandlerBase.HandleAsync(HttpContext httpContext) 在 Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.Invoke(HttpContext 上下文)在 Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.Invoke(HttpContext 上下文)在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication1 application) fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HLJNNKCOIPS6", Request id "0HLJNNKCOIPS6:00000002": An unhandled exception was thrown by the application. System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://login.botframework.com/v1/.well-known/openidconfiguration'.
at Microsoft.IdentityModel.Protocols.ConfigurationManager
1.GetConfigurationAsync(CancellationToken 取消)在 Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync() at Microsoft.Bot.Connector.Authentication.JwtTokenExtractor.ValidateTokenAsync(String jwtToken, String channelId) at Microsoft.Bot.Connector.Authentication.JwtTokenExtractor.GetIdentityAsync(String scheme, String parameter, String channelId) at Microsoft.Bot.Connector.Authentication.JwtTokenExtractor.GetIdentityAsync(String authorizationHeader, String channelId) at Microsoft.Bot.Connector.Authentication.ChannelValidation.AuthenticateChannelToken(String authHeader, ICredentialProvider credentials, HttpClient httpClient, String channelId) at Microsoft.Bot.Connector.Authentication.ChannelValidation.AuthenticateChannelToken(String authHeader, ICredentialProvider credentials, String serviceUrl, HttpClient httpClient, String channelId) at Microsoft.Bot.Connector.Authentication.JwtTokenValidation.ValidateAuthHeader(String authHeader, ICredentialProvider credentials, IChannelProvider channelProvider, String channelId, String serviceUrl, HttpClient httpClient) at Microsoft.Bot.Connector.Authentication.JwtTokenValidation.AuthenticateRequest(IActivity activity, String authHeader, ICredentialProvider credentials, IChannelProvider provider, HttpClient httpClient) at Microsoft.Bot.Builder.BotFrameworkAdapter.ProcessActivityAsync(String authHeader, Activity activity, BotCallbackHandler callback, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Integration.AspNet.Core.Handlers.BotMessageHandler.ProcessMessageRequestAsync(HttpRequest request, IAdapterIntegration adapter, BotCallbackHandler botCallbackHandler, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Integration.AspNet.Core.Handlers.BotMessageHandlerBase.HandleAsync(HttpContext httpContext) at Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication1 应用程序)信息:Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 请求在 21679.9889ms 500 信息中完成:Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 请求在 14958.2414 毫秒内完成 500 信息:Microsoft.AspNetCore.Hosting.Internal.WebHost[1] 请求开始 HTTP/1.1 POST http://127.0.0.1:41826/CONFROOM/iisintegration 0 信息: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] 请求在 0.373 毫秒内完成 202 应用程序正在关闭...

请帮助。 谢谢。

【问题讨论】:

  • 能否更新您的问题以包含您的 web.config 文件?
  • 这是一个运行在 .NET core 2.0 上的 BOT Framework V4 应用程序,所以没有 web.config 文件,它有 appsettings.json 文件。
  • 您确定它不起作用吗?默认情况下,您无法访问该目录,因此无法访问 403.14。您是否尝试使用模拟器发布到 /api/messages 端点?
  • 我还了解到,根据 Drew 的建议,BOT 本身会在发布时生成 web.config 文件。抱歉回复晚了,但我的问题仍然存在。我添加了由 BOT 生成的 web.config 代码和日志。
  • @drew-marsh 任何帮助表示赞赏。

标签: azure iis botframework bots azure-bot-service


【解决方案1】:

这是 IIS 的身份验证问题。我们必须使用具有所有权限的用户帐户,即管理员来配置以下内容

  1. 应用程序池标识
  2. 托管应用程序的 IIS 身份验证和授权(连接方式)。

我删除了我为 OAuth 等身份验证编写的所有代码。

感谢大家的宝贵时间。

【讨论】:

    【解决方案2】:

    根据您添加到问题中的异常详细信息,这是根本问题:

    应用程序引发了未处理的异常。 System.InvalidOperationException:IDX20803:无法从“https://login.botframework.com/v1/.well-known/openidconfiguration”获取配置。 ---> System.IO.IOException:IDX20804:无法从“https://login.botframework.com/v1/.well-known/openidconfiguration”检索文档。 ---> System.Net.Http.HttpRequestException: 连接尝试失败,因为连接的一方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应

    现在,如果您只是使用浏览器导航到该位置,您应该会看到响应包含描述 OpenID 配置的 JSON 元数据文档没有问题:

    {
      "issuer": "https://api.botframework.com",
      "authorization_endpoint": "https://invalid.botframework.com",
      "jwks_uri": "https://login.botframework.com/v1/.well-known/keys",
      "id_token_signing_alg_values_supported": [
        "RS256"
      ],
      "token_endpoint_auth_methods_supported": [
        "private_key_jwt"
      ]
    }
    

    好消息是您的机器人似乎运行良好。这实际上表明 bot 运行并且已经足够远以至于它正在验证请求,所以这是一个好兆头。这个例外在我看来是,无论您的机器人在哪里托管,都可能无法向 Internet 发出出站请求。那可能吗?它需要能够验证来自机器人框架的 JWT 令牌的真实性,并最终需要它通过机器人框架将响应发送回客户端。您可能需要将发送到 botframework.com 域的 HTTP 请求列入白名单。

    【讨论】:

    • 感谢 Drew 抽出宝贵时间。我想在这里强调一下,我们已经将 BOT V3 托管在我们现在正在尝试 BOT V4 的服务器上。 BOT V3 从过去 2 年开始就在那里托管,并且运行良好。 BOT 和 azure 之间的所有请求都适用于 BOT V3。我没有得到 BOT V4 到底有什么问题。我在 Azure 上使用了 BOT 通道注册,并将我的 BOT v4 应用程序路径指定为 Azure 中的消息传递端点,并且我在同一台服务器上安装了 webchat IFrame。
    • 那么这确实令人困惑,但异常非常明确......尝试连接和/或下载该元数据文档时超时。
    • 您好,我可以通过使用 Azure 应用程序注册注册应用程序来解决问题,然后在 OpenID Connect 身份验证的帮助下从我的 BOT 核心应用程序连接相同的应用程序,所以现在我可以下载了元数据。
    【解决方案3】:

    我认为 Drew Marsh 在他的回复中发现了问题,这可能是 web.config 问题。

    如果您要在 IIS 中托管 .net 核心应用程序,IIS 仍需要应用程序目录中的 web.config,该目录将具有处理程序映射和 aspNetCore 路径。

    基本上,IIS 必须知道应用程序是一个 .net 核心应用程序以及要运行什么代码。

    我可能错了,但这看起来像是把所有东西都当作一个静态文件来对待。

    I get this error if I remove the web.config from a working .net core app hosted in IIS.

    看起来几乎与您的错误相同,我也犯了类似的错误。

    在将我的项目发布为 IIS Web 部署包时,我通常很幸运。这往往会创建所有必要的位。

    工作的 web.confg 可能看起来像这样。

    <configuration>
          <system.webServer>
            <handlers>
              <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
            </handlers>
            <aspNetCore processPath="dotnet" arguments=".\blagh.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
          </system.webServer>
    </configuration>
    

    【讨论】:

    • 嗯,是的,这就是我问的原因。但是,您实际上并不需要自己手动创建该 web.config 文件。当您发布应用程序时,应该为您创建一个(例如dotnet publish)。
    猜你喜欢
    • 2019-07-27
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多