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:
- 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 - Checked that my app pool is set to v4.0 and integrated mode as also suggested in the link from #1
- Adding
runAllManageModulesForAllRequests="true"
to the modules section of my Web.config as suggested at How to get IIS to recognize OWIN startup class? - Adding
app.UseStageMarker(PipelineStage.MapHandler);
to the end the OWIN startup class as suggested in the post from #3 - 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=\"Web\" /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>