简体   繁体   中英

ASP.Net Core Web API, deployed under IIS is returning 404

I have a new Web API developed in ASP.NET Core. This Web API is supposed to be deployed in IIS and will have to work over SSL, so I have the [HttpsRequired] attribute on all my controllers. I struggle to make it work while deployed, so for now I relaxed the requirements and commented out those attributes. Doing so, I was able to create two bindings in IIS, one for HTTPS and one for HTTP. Given that my Web API is created in ASP.NET Core, I followed the deployment steps Rick Strahl has in his excellent blog post . I have selected "No Managed Code" for the .NET CLR version. The IIS machine is a 64-bit Windows Server 2012 R2 environment - not sure whether this matters or not. The .NET Core Windows Server Hosting bundle has been installed on the server and I can see the AspNetCoreModule listed in the Modules grid.

If i try to access the Web Api (I created a very simple GET method that returns some information regarding the assembly) with Fiddler, I get a 404 error. For now, i run Fiddler on the same machine, so I tried all combinations (localhost, IP address and full machine name in the domain).

No errors are logged in the EventViewer. Does anyone have any suggestion on how to troubleshoot this issue?

TIA, Eddie

EDIT1: Here is my controller:

[Route("api/info")]
//[RequireHttps]
public class InfoController : Controller
{
  private ITncRepository _repository;
  public static ApplicationAssemblyDetails ApplicationAssemblyDetails { get; set; }

  public InfoController(ITncRepository repository)
  {
     _repository = repository;
     ApplicationAssemblyDetails = ApplicationAssemblyDetails.Current;
  }

  [HttpGet("")]
  public JsonResult Get()
  {
     return Json(new WebApiInfoModel()
                     {
                        CurrentTime  = DateTime.Now,
                        CurrentUtcTime = DateTime.UtcNow,
                        AssemblyName = ApplicationAssemblyDetails.ApplicationAssembly.FullName,
                        VersionNumber = ApplicationAssemblyDetails.VersionNumber,
                        BinFolder = ApplicationAssemblyDetails.BinFolder,
                        BuildMode = ApplicationAssemblyDetails.BuildMode,
                        TradeMark = @" © 2016-2017 * SomeCompany (www.somecompany.com)"
     });
  }
}

The ApplicationAssemblyDetails is a nuget package that gives some info about the current assembly. WebApiInfoModel is my model class for the Web API Information I want to pass back as a test to the client.

The web.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath=".\My_ASP_NET_Core_Web_API.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="true" />
  </system.webServer>
</configuration>

Finally, to answer your last question, Ignas, I use a Publishing Profile that uses the File system as a method, targets the .NET Framework 4.5.2, using the release configuration. Given that my project is a Web API and not an MVC 6 Web Application, the publishing package creates a stand-alone application. Since the clients need to call my Web API using SSL, I think that it has to be hosted in IIS, so running the standalone application would not work. Of course, for testing purposes, I could try to run it. That's why I commented out the [HttpsRequired] attribute. I will try that and report back, but for now I hope I gave you all the information you required.

I'm having a setup very close to yours (Asp.Net core, Web API, IIS, HTTPS ...) working fine on my end.

I faced the same issue at some point because I was not using the proper path to access my controller/action, it depends on how you deployed it under IIS. For instance, in my case when I use Kestrel directly it goes through a URL like that:

http:// localhost:5000/controllerName/actionName

But I can also contact my Web API via IIS and in that case I need to use a URL like that:

http:// localhost:5001/ applicationName /controllerName/actionName

Have you created an application under IIS that could explain you getting a 404 because you would not use the proper path?

For instance, in my case:

screenshot of the asp.net core api under iis

And I'm accessing it, through the URL:

https: //servername:serverport/ RequestPortalAPI /ControllerName/ActionName

In the end, it was a matter of properly configuring Widows Authentication. For Fredrik and anyone else reading this post for a solution, these are the steps I performed:

  1. In IIS, in the Authentication form for my Web API, I disabled Anonymous Authentication and I enabled Windows Authentication:

在此处输入图片说明

Make sure that "Negotiate" is at the top of the list for Enabled Providers:

在此处输入图片说明

  1. In the Application Pools, I configured my Web API to run under an account that the UIT department of my client has given me:

在此处输入图片说明

  1. The configuration file of my Web API (web.config) contains the following settings:

在此处输入图片说明

Now we are getting into the dark areas of the problem. In order to use Windows Authentication and let the credentials of the caller be passed through to the backend (in my case a SQL Server database), the Web API has to be configured to use Kerberos. I found this after I opened a ticket with Microsoft and I worked closely with one of their engineers. For this to happen, you need to follow these steps:

  1. Create a Service Principal Name (SPN) for your Web API and the domain account it runs under. You need to run this command:

    在此处输入图片说明

Where hostname is the fully qualified domain name of your Web API. The Domain\\Username are the domain account under which the Web API is running. You need special domain privileges, so you may want to involve someone from IT. Also, from now on, you need to access your Web API by the full domain name, not by IP address. IP address won't work with Kerberos.

  1. Also, with the help of your IT person, you need to enable delegation for any service using Kerberos for the domain account under which you run your Web API. In the Active Directory Users and Computers, locate the account you use to run your Web API, bring up its properties, click on the Delegation tab and enable the second option "Trust this user for delegation to any service (Kerberos Only):

在此处输入图片说明

We have also made some changes on the server that runs our database, but I am not 100% those are truly required, so I won't add them here because I don't even know if you use SQL Server or some other backend repository.

Let me know if you need those as well and I will add them later.

Good luck, Eddie

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM