0

I am migrating and existing angular js app to angular while sticking to an existing api. I tried to implement a logon (ASP NET / OWIN) and encountered following situation after making a http request to logon endpoint: All possible server responses (2xx,4xx,5xx) could not be fetched in javascript code. After researching I found the cause: CORS This is because new angular app runs on different port than the locally hosted api while the old angular js ab is being hosted on the same port.

So I added following to ValidateClientAuthentication in API:

  context.Response.Headers.Append("Access-Control-Allow-Origin", "http://localhost:4200");
            context.Response.Headers.Append("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");

Now I am finally able to fetch 2xx responsed but still do not get 4xx and 5xx results. Why is that? And how is it possible that API calls to other endpoints of same API do not require setting those headers?

UPDATE: I receive this error message for all 4xx responses even if I have added those headers in API:

:63323/api/logon:1 Failed to load resource: the server responded with a status of 400 (Bad Request)
vendor.js:68504 ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
    at subscribeTo (vendor.js:158625)
    at subscribeToResult (vendor.js:158782)
    at CatchSubscriber.error (vendor.js:151269)
    at MapSubscriber.Subscriber._error (vendor.js:147999)
    at MapSubscriber.Subscriber.error (vendor.js:147979)
    at XMLHttpRequest.onLoad (vendor.js:24621)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:2785)
    at Object.onInvokeTask (vendor.js:70070)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:2784)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (polyfills.js:2557)

UPDATE 2: this is the code that handles http request:

 return this.httpClient
            .post(this.appConfigService.buildAuthorizationUrl('/logon'), data, {
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            })
            .toPromise()
            .then(
                (response: any) => {
                    // hit when 2xx and cors headers present
                },
                (error: any) => {
                    // never hit
                }
            )
            .catch(error => {
                    // never hit
            });

UPDATE 3: As I understood CORS middleware might(?) drop all heades in case 4xx or 5xx responses which will prevent browsers from fetching responses. But like you can see my 400 response from a different endpoint on my api seems to be valid:

HTTP/1.1 400 Bad Request
Cache-Control: private,no-cache, no-store, must-revalidate
Pragma: no-cache
Content-Length: 112
Content-Type: application/json; charset=utf-8
Expires: 0
Server: Microsoft-IIS/10.0
Access-Control-Allow-Origin: http://localhost:4200
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcS2F5IFphbmRlclxEb2N1bWVudHNcZXZlXFNvdXJjZVxJbmZvcnNIVC5HZW5lc2lzQXBpXGF1ZGl0dHJhaWw=?=
X-Powered-By: ASP.NET
X-UA-Compatible: IE=edge
Date: Wed, 06 Nov 2019 16:01:08 GMT

[{"ErrorMessage":"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.","PropertyName":"Exception"}]

still I encounter the mentioned error message.

yBother
  • 648
  • 6
  • 25

1 Answers1

2

Most likely your ASP.NET backend doesn't have CORS enabled, according to the fact that if you set it manually you're able to make a request. If you set a header (e.g. Content-Type) to your request, whether it was manually set or automatically, Angular sends a preflight request for the backend to determine if the resource can be accessed with the specific request headers or not.

There's a built-in support for preflight request handling, which you can enable using attributes to your controllers, and a little configuration in the initial startup class.

For ASP.NET (.NET Framework based) check this guide: https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

For ASP.NET Core check this one: https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.0

Martin Frøhlich
  • 602
  • 6
  • 10
  • okay thank you but why do I get this (see update) response for 400 responses? – yBother Nov 06 '19 at 09:47
  • That's a type error. You provided an invalid type to a function call or a callback. Check your code, or post the relevant part here in an update so we can take a look at it. – Martin Frøhlich Nov 06 '19 at 10:13
  • I don't think so -> see Update 2 – yBother Nov 06 '19 at 11:00
  • Hm I found a topic (I believe it was here on stackoverflow) that I cannot find anymore that helped a little bit: UseCors() should be at the very top and .EnableCors() can be dropped. Now I don't need to manually set those headers but the 4xx,5xx issue remains. The linked topic is for .NET CORE and does not apply to my situation. – yBother Nov 06 '19 at 13:46
  • where can I find my favorite topics? it was this topic https://stackoverflow.com/questions/24989769/cors-is-not-working-in-web-api-with-owin-authentication – yBother Nov 06 '19 at 13:47
  • I finally found the issue (I did not write that part of code): front end is using an interceptor that for some reason does not return errors correctly. – yBother Nov 06 '19 at 16:46