3

I am hosting my BOT Framework V4 BOT on IIS. Server Configuration is as below

  1. Windows Server 2012 R2
  2. IIS 8.5

I have also installed dotnet-hosting-2.2.1-win.exe which is essential in order to host BOT V4. I have set application pool as No Managed Code. I have set the path of the folder where Startup.cs file resides. Also Please find the attachment of logs generated by BOT. Still, it is not working the error is as below

HTTP Error 403.14 - Forbidden The Web server is configured to not list the contents of this directory.

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

Below is the web.config code

<?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>

Below are the logs generated by BOT

Hosting environment: Production Content root path: E:\Project\DotNetCoreApps\ConfRoomPub\WithPII\publish Now listening on: http://127.0.0.1:41826 Application started. Press Ctrl+C to shut down. info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://example.com/ConfRoom/ info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 GET http://example.com/ConfRoom/ info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2] Sending file. Request path: '/default.htm'. Physical path: 'E:\Project\DotNetCoreApps\ConfRoomPub\WithPII\publish\wwwroot\default.htm' info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6] The file /default.htm was not modified info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 184.4402ms 304 text/html info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 188.1919ms 200 text/html info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 POST http://example.com/ConfRoom/api/messages application/json; charset=utf-8 373 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 POST http://example.com/ConfRoom/api/messages application/json; charset=utf-8 359 fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HLJNNKCOIPS7", Request id "0HLJNNKCOIPS7: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'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://login.botframework.com/v1/.well-known/openidconfiguration'. ---> System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 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.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.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(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 cancel) --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.ConfigurationManager1.GetConfigurationAsync(CancellationToken cancel) at 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 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 cancel) at 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 application) info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 21679.9889ms 500 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 14958.2414ms 500 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Request starting HTTP/1.1 POST http://127.0.0.1:41826/CONFROOM/iisintegration 0 info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Request finished in 0.373ms 202 Application is shutting down...

Kindly help. Thank you.

Amol Pawar
  • 251
  • 1
  • 15
  • Can you please update your question to include your web.config file? – Drew Marsh Jan 10 '19 at 07:15
  • This is a BOT Framework V4 application which runs on .NET core 2.0, so there is no web.config file, it have appsettings.json file. – Amol Pawar Jan 10 '19 at 08:15
  • Are you sure it's not working? By default you cannot access the directory, thus the 403.14. Did you try to post to the /api/messages endpoint using the emulator? – Sotiris Panopoulos Jan 10 '19 at 13:30
  • I also came to know and as suggested by Drew, BOT itself generate the web.config file at the time of publishing. Sorry for the late reply, but my issue still exists. I have added web.config code and logs generated by BOT. – Amol Pawar Jan 15 '19 at 10:38
  • @drew-marsh Any help is appreciated. – Amol Pawar Jan 21 '19 at 05:46
  • My web site is having a valid certificate and I have also added support for TLS 1.2 in registry along with TLS 1.0 & 1.2, but still the same issue. – Amol Pawar Jan 21 '19 at 10:12
  • We have sorted out that it is proxy issue, the URL which is listed in error message is not able to bypass the proxy server. We have mentioned proxy setting in Web.config but it is not taking effect. We have checked logs with firewall team and they are saying they do not get any request logs. Do i have to mention proxy somewhere is code and if yes then where exactly? – Amol Pawar Feb 04 '19 at 09:29

3 Answers3

0

I think Drew Marsh found the problem in his reply, this is probably a web.config issue.

If you are going to be hosting a .net core app in IIS, IIS will still require a a web.config in the application directory which will alteast have a handler mapping and a aspNetCore path.

Basically, IIS has to know that the application is a .net core app and what code to run.

I might be wrong, but that looks like its treating everything like a static file.

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

Looks nearly identical to your error, and I made a similar mistake.

I've generally had good luck with publishing my project as a IIS Web Deploy Package. That tends to create all the necessary bits.

A working web.confg may look something like this.

<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>
A P
  • 41
  • 6
  • Well, yes, this is why I was asking. However, you don't actually need to manually create that web.config file yourself. One should be created for you when you publish your app (e.g. `dotnet publish`). – Drew Marsh Jan 10 '19 at 16:45
0

According to the exception details you added to your question, this is the root problem:

An unhandled exception was thrown by the application. System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://login.botframework.com/v1/.well-known/openidconfiguration'. ---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://login.botframework.com/v1/.well-known/openidconfiguration'. ---> System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

Now, if you just go navigate to that with your browser, you should see there's no problem getting a response that includes this JSON metadata document describing the OpenID configuration:

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

The good news is your bot seems to be executing fine. This actually indicates that the bot ran and got far enough that it was authenticating the request, so that's a good sign. What this exception smells like to me is that wherever your bot is hosted may not have the abillity to make outbound requests to the internet. Is that possible? It needs that to be able to verify the authenticity of the JWT token coming from bot framework and, ultimately, will need it to send responses back to clients through the bot framework. You may need to work to whitelist HTTP requests to the botframework.com domain.

Drew Marsh
  • 33,111
  • 3
  • 82
  • 100
  • Thanks, Drew for your time. I would like to highlight over here that we are already having BOT V3 hosted on the server on which we are now trying BOT V4. BOT V3 is hosted there from last 2 years and it is working fine. All the request to & from the BOT and azure are working fine for BOT V3. I am not getting what exactly wrong with BOT V4. I have used BOT channel registration on Azure and have specified my BOT v4 application path as a messaging endpoint in Azure and I have webchat IFrame on the same server to try. – Amol Pawar Jan 22 '19 at 09:05
  • Well then that really is confusing, but the exception is pretty unambiguous... it is timing out trying to connect and/or download that metadata document. – Drew Marsh Jan 22 '19 at 15:39
  • Hello, I am able to resolve the issue by registering an Application with Azure Application Registration and then connected the same application from my BOT core app with help of OpenID Connect authentication, so now i am able to download metadata. – Amol Pawar Feb 19 '19 at 11:29
0

It was an authentication issue of IIS. We had to use user account which has all privileges i.e administrator to configure below things

  1. Application Pool Identity
  2. IIS authentication and authorization of Hosted application (Connect as).

I removed all the code which I wrote for authentication like OAuth etc.

Thanks all for your time.

Amol Pawar
  • 251
  • 1
  • 15