8

I hosted dotnet core 2.2 web api application to local IIS. When i run hosted site, site is working. I am trying to do login from angular, it is not working.

It says Access to XMLHttpRequest at 'http://192.168.43.143:100/Auth/Login' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Note: It was working locally. No CORS policy issue occured

I have added cors policy in ConfigureServices and provide middleware to add UseCors().

public void ConfigureServices(IServiceCollection services)
{
   services.AddCors(c =>  
            {    
                c.AddPolicy("AllowOrigin", options => options.AllowAnyHeader()
                    .AllowAnyMethod().AllowAnyOrigin()
                    .SetIsOriginAllowed((host) => true).AllowCredentials());  
            });

   services.Configure<MvcOptions>(options => {
                options.Filters.Add(new CorsAuthorizationFilterFactory("AllowOrigin"));
            });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseCors("AllowOrigin");
    app.UseMvc();
}

My installed software details are given below,

  • System: Windows 10
  • DotNet Core SDK: 2.2.110 & 3.1.201
  • Windows Server Hosting: 2.2.1

Basic code is given below for your reference.

Dot Net Core Web API:

Program.cs

public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseUrls("http://localhost:4000")
                .UseStartup<Startup>();
    }

StartUp.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddCors(c =>
            {
                c.AddPolicy("AllowOrigin",
                    options => options.WithOrigins("*").AllowCredentials().AllowAnyHeader().AllowAnyMethod()
                );
            });

            // DbContext and JWT implementation done

            // Authorization filter added
            
            services.Configure<MvcOptions>(options => {
                options.Filters.Add(new CorsAuthorizationFilterFactory("AllowOrigin"));
            });

            //Dependence Injunction done
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            // app.UseForwardedHeaders();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseAuthentication();  //it is used to authorize jwt tokens
            app.UseDefaultFiles();
            app.UseStaticFiles();
            app.UseHttpsRedirection();
            app.UseCors();
            app.UseMvc();
        }

Hosted Web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\TestAPI.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
    </system.webServer>
  </location>
</configuration>
<!--ProjectGuid: 9aea96ef-cfc4-4231-9bfb-78f4efec933f-->

launchSettings.json:

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:4000",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      //"launchUrl": "api/values",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "TestAPI": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "http://localhost:4000/values",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Angular 7:

Interceptor code is given

const authReq = this.currentuser
      ? request.clone({
        headers: request.headers.set('Authorization', 'Bearer ' + this.currentuser)
          .set('Access-Control-Allow-Origin', '*')
          .set('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
          .set('Content-Type', request.headers.get('content-type') ?
            request.headers.get('content-type') : 'application/json')
      })
      : request.clone({
        headers: request.headers
        .set('Access-Control-Allow-Origin', '*')
          .set('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE, OPTIONS')
          .set('Content-Type', 'application/json')
      });
    return next.handle(authReq).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401) {
          // auto logout if 401 response returned from api
          this.authenticationService.logout();
          // tslint:disable-next-line: deprecation
          location.reload(true);
        }
        return throwError(error);
      }));

IIS Configuration image given below enter image description here

Venkateswaran R
  • 438
  • 2
  • 5
  • 18
  • https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module – Lex Li Jul 12 '20 at 14:54
  • 1
    After adding also same error occured – Venkateswaran R Jul 12 '20 at 17:49
  • I would like to know before deploying into server, what are code has to be written in Program.cs & Startup.cs file. Like UseIISInegration(), UseKestral() and software installation. Will we get version mismatch issue for installation about deploy? – Venkateswaran R Jul 12 '20 at 18:05

3 Answers3

3

I had to move the CORS policy into the web.config file for IIS to manage.

I couldn't persuade AddCors to work at all when hosted by reverse proxy IIS.

After a lot (days and days and days) of trial and error, I resorted to letting IIS manage it. This means that I have to configure CORS in two places (at least not at the same time though) if I ever need to separate my ASP.NET (Net5.0) application, but I doubt that would ever happen (Famous last words...)

I cannot help but wander if this is by design - if IIS purposefully disables the CORS handling in Kestrel? If you think about it, the OPTIONS method hits the IIS public endpoint, gets relayed to the .NET Core hosted application and a go/no-go is transmitted back in the response. This constitutes a two-step call every time a request is made. Now that is a lot of relaying that can be mitigated if handled on the first layer.

I hope this helps in SOME way, if not at least to console you in the knowledge that you are NOT alone.

1

I tested your code snippet of solving the CORS issue, it works perfectly on my side. My only question is why the default request is sent to the HTTP scheme, instead of the HTTPS service endpoint.

Access to XMLHttpRequest at 'http://192.168.43.143:100/Auth/Login'

As far as I know, Asp.Net Core WebAPI2.2 uses https redirection by default, which may be the cause of the problem.

  app.UseHttpsRedirection();
            //app.UseCors("AllowOrigin");
            app.UseMvc();

Besides, I suggest you try another way to solve the CORS issue.
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1#enable-cors
Such as the below way, we decorate the Values controller with EnableCors attribute to support CORS.
Values Controller.

[Route("api/[controller]")]
    [ApiController]
    [EnableCors("MyPolicy")]
    public class ValuesController : ControllerBase
    {

Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
           services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddCors(options =>
            {
                options.AddPolicy("MyPolicy", builder =>
                 {
builder.WithOrigins("*").AllowCredentials().AllowAnyHeader().AllowAnyMethod();
                 });
            });
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
     
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseCors();

            app.UseMvc();
        }

Finally, if we enabled other authentication modes in IIS, such as windows authentication, we had better install the IIS Cors module to support CORS. This is also helpful.
https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
Feel free to let me know if the problem persists.

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22
  • 1
    Thank you for your help. The given solution also not working. I am trying to host to my local IIS. I put enablecors property from globally like services.Configure(options => { options.Filters.Add(new CorsAuthorizationFilterFactory("AllowOrigin")); }); and called those cors policy name like app.UseCors("AllowOrigin"); – Venkateswaran R Jul 14 '20 at 18:28
  • Why was the default API request sent to the HTTP scheme? I would like to know more details about it. In addition, have you tried to solve the CORS issue by using the IIS CORS extension? – Abraham Qian Jul 15 '20 at 09:59
  • I am a new to deploy the application to IIS. I installed IIS CORS extension, still not working – Venkateswaran R Jul 15 '20 at 17:23
  • I connected through my mobile internet and tried to host into IIS. So that only my id is generating as http://192.168.43.143:4000/. – Venkateswaran R Jul 15 '20 at 18:52
  • About the IIS CORS extension, after installing the extension, create a webconfig file under the root directory of the website and add the below segment. – Abraham Qian Jul 16 '20 at 09:07
  • Post the error details if it doesn’t work. About the default address that we sent the HTTP request to. Did you add an https binding to the WebAPI project in the IIS site binding module? https://i.stack.imgur.com/dgwT8.png – Abraham Qian Jul 16 '20 at 09:07
  • I have provided all information. Kindly check. After adding enable cors property in web.config also not working. Still i faced Access to XMLHttpRequest at 'http://192.168.43.143:200/Auth/Login' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If i added Access-Control-Allow-Origin in web.config then error message says There are multiple origin presents '*, *' – Venkateswaran R Jul 16 '20 at 18:04
  • We should ensure that the Asp.Net WebAPI has already worked properly after published in IIS. the base address of the API project is provided in the IIS site binding module. Can you test the service in the PostMan software? – Abraham Qian Jul 17 '20 at 09:23
  • When i try to call 192.168.43.143:200/Auth/Login method from postman, it shows 500 internal server error. If i call http://192.168.43.143:200/auth/login from browser This 192.168.43.143 page can’t be foundNo webpage was found for the web address: http://192.168.43.143:200/auth/login error shows – Venkateswaran R Jul 18 '20 at 06:36
  • Yes, now the question is clear, the WebAPI project might work improperly. Please first try to host a Hello-world API project and test it. This can keep us go further. – Abraham Qian Jul 20 '20 at 09:45
  • I am having one doubt. I have used dbcontext as a packages and has been used in web api project. When we are hosting, do i need to do any configuration setup to configure package path in IIS? – Venkateswaran R Jul 20 '20 at 18:18
  • I tried to call one anonymous method to return data from database using postman. It returns 500 internal server. It might be a problem with Package reference path. – Venkateswaran R Jul 20 '20 at 18:27
  • I don't think so, there is no need to configure the Package Reference path. All these settings are included in the Csproj file and will be compiled into the runtime file. – Abraham Qian Jul 21 '20 at 09:59
0

I encountered a similar error, in which I had setup the CORS Middleware in my project.cs, confirmed it working on my localhost - then it stopped working when on my remote server.

The solution was very simple, though took me some time to figure out. On my localhost I was sending the api requests to http:// but the server wanted the api to be called with https://.

I am unsure the reason, but a solution to try if anyone is encountering a similar situation is to call your api with an https:// request instead of http://