0

I have a web application written in AngularJS that uses the OWIN middleware for OAuth 2 authentication and ASP.Net 4.5 Web API to provide data access.

The entire app runs fine locally when launched directly from Visual Studio 2015 Community (using the default of Cassini). However, when I publish it to IIS 8 on my local server that is running Windows Server 2012 I get 404 errors for any URL that I attempt to request from Web API as well as the OAuth token URL endpoint.

I have confirmed via logging that the OWIN startup class is being started and running successfully. See the end of the post for the code from both this startup class and my Web API config class.

I am entirely out of ideas on where to go next. What do I need to do to get this thing working? Any help is greatly appreciated.

I have tried the following with no luck as to a resolution:

  1. Make sure that Microsoft.AspNet.WebApi.WebHost has been added via Nuget and is present in the bin folder in the sites folder under wwwroot as suggested at Owin Middleware results in 404 on server
  2. Checked that my app pool is set to v4.0 and integrated mode as also suggested in the link from #1
  3. Adding runAllManageModulesForAllRequests="true" to the modules section of my Web.config as suggested at How to get IIS to recognize OWIN startup class?
  4. Adding app.UseStageMarker(PipelineStage.MapHandler); to the end the OWIN startup class as suggested in the post from #3
  5. Adding the new handler <add name="Owin" verb="*" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" /> specifically for OWIN as suggested at OWIN WebApi project on IIS 10 gives 404 on all operations

Update 1

I realized that I inadvertently neglected to mention in the orginal post that IIS is using its default settings and I'm able to load the home page of the site and other pages. The requests to get the data via Web API or login just bomb with 404s. Will update with the modules installed in IIS when possible later today.

OWIN Startup Class

using System;
using System.Web;
using System.Web.Http;
using System.Collections.Generic;
using System.Linq;

using Owin;
using Microsoft.Owin;
using Microsoft.Owin.Hosting;
using Microsoft.Owin.Security.OAuth;
using Microsoft.Owin.Extensions;

using WebApplication.application.Authorization;
using log4net;

namespace WebApplication.App_Start
{
    public class OwinStartup
    {
        private static ILog logger = LogManager.GetLogger("OWIN Startup");

        public void Configuration(IAppBuilder app)
        {
            logger.Debug("Beginning to configure OWIN.....");

            HttpConfiguration config = new HttpConfiguration();

            WebApiConfig.Register(config);
            app.UseWebApi(config);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

            logger.Debug("Web API registered with OWIN..... CORS enabled");

            ConfigureOAuth(app);

            logger.Debug("Adding MapHandler Stage Marker.....");

            app.UseStageMarker(PipelineStage.MapHandler);

            logger.Debug("OWIN has been configured... end of OwinStartup class method Configuration...");
        }

        public void ConfigureOAuth(IAppBuilder app)
        {
            logger.Debug("Beginning OWIN OAuth configuration.....");

            OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/oauth/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new SimpleAuthorizationServerProvider()
            };

            // Token Generation
            app.UseOAuthAuthorizationServer(OAuthServerOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

            logger.Debug("Completed OWIN OAuth configuration");
        }
    }
}

Web API Configuration Class

using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace WebApplication
{
    public static class WebApiConfig
    {
        private static ILog logger = LogManager.GetLogger("WebApiConfig");

        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            logger.Debug("Beginning configuration of Web API...");

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            logger.Debug("Web API has been configured");
        }
    }
}

Web.Config

    <?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>

  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <appSettings>
    <add key="log4net.Internal.Debug" />
    <add key="owin:appStartup" value="Personal_Food_Database.App_Start.OwinStartup" />
    <add key="owin:AutomaticAppStartup" value="true" />
  </appSettings>

  <system.web>
    <compilation targetFramework="4.5.2" debug="true" />
    <httpRuntime targetFramework="4.5.2" />
    <customErrors mode="Off" />
    <authentication mode="None" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="FormsAuthentication" />
    </modules>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <add name="Owin" verb="*" path="*" type="Microsoft.Owin.Host.SystemWeb.OwinHttpHandler, Microsoft.Owin.Host.SystemWeb" />
    </handlers>
  </system.webServer>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

  <log4net>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="\Logs\log.txt" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maximumFileSize value="10MB" />
      <maxSizeRollBackups value="5" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ISO8601} [%logger] %level - %message%newline%exception" />
      </layout>
    </appender>

    <root>
      <level value="DEBUG" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>

  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
</configuration>

Packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net452" />
  <package id="log4net" version="2.0.5" targetFramework="net452" />
  <package id="Microsoft.AspNet.Cors" version="5.0.0" targetFramework="net452" />
  <package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net452" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.1" targetFramework="net452" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.1" targetFramework="net452" />
  <package id="Microsoft.Net.Compilers" version="1.2.2" targetFramework="net452" developmentDependency="true" />
  <package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Cors" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Diagnostics" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="8.0.3" targetFramework="net452" />
  <package id="Owin" version="1.0" targetFramework="net452" />
  <package id="Twitter.Bootstrap" version="2.2.2" targetFramework="net452" />
</packages>
Community
  • 1
  • 1
Josh
  • 23
  • 5
  • Are you sure you have the bindings in IIS set up correctly? – DavidG Aug 18 '16 at 00:46
  • I am not sure of that. Is there documentation that you know of that I could follow to ensure that the bindings are set up correctly? – Josh Aug 18 '16 at 01:58
  • I'm just now realizing that in my initial post I inadvertently neglected to mention, and it is likely worth noting, that IIS is using its default settings and I'm able to load the home page of the site and other pages. The requests to get the data via Web API or login just bomb with 404s. I'll update the original post to also include this information. – Josh Aug 18 '16 at 02:20
  • So you have the relevant parts of IIS installed too? All of the asp stuff for example? – DavidG Aug 18 '16 at 03:00
  • While attempting to follow a guide to ensure I have all of the proper modules installed (including outside of the IIS section) I appear to have messed it up further to where now all requests are returning 404s. Seeing as that is likely a separate question I will attempt to troubleshoot and post back here once I get all the modules installed. Appreciate the help so far! – Josh Aug 19 '16 at 02:02
  • I found an answer at http://stackoverflow.com/questions/30563814/owin-oauth-localhost-token-returns-404 Hope this help. – Giant Penguin Apr 20 '17 at 07:22

0 Answers0