AngularJS $http Authorize header not sent properly to RESTful service when developing locally but works in Cordova - ajax

I am developing an iOS application utilizing the Ionic framework with Cordova and have run into a bit of a snag in my dev cycle. While running on my local dev web server, any RESTful call happening from the $http service is failing with a 401 Not Authorized error even though I am passing the Authorization header. Interestingly enough, the call works fine once I build the app and deploy onto the iOS Emulator.
FWIW, the api calls are to an Atlassian Confluence api.
CORS doesn't seem to be the issue as that has been configured, tested and working on non-authenticated calls.
Here is the very basic call that is failing within the browser but working on the emulator when using the same headers:
$http.defaults.headers.common['Accept'] = 'application/json';
$http.defaults.headers.common.Authorization = 'Basic xxxxxxxxxxxxxx';
$http.get('https://www.example.com/rest/prototype/1/search/site?type=blogpost&spaceKey=TESTSPACE&os_authType=basic')
.success(function (data, status) {
this.serviceData = data;
})
.error(function (data, status) {
console.log(status, data.result);
});
I am sending two custom headers: Accept: application/json and Authorization: Basic *** If I run the application in Chrome with the above service configuration, I see the following Request Headers. There is an added Access-Control-Request-Headers that mentions the Accept and Authorization headers, but those headers are not there. I see the following Request Headers going across the wire:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,nl;q=0.6
Access-Control-Request-Headers:accept, authorization <!---- This is added but there is no Authorization Header
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:www.example.com
Origin:https://local.example-client.com
Pragma:no-cache
Referer:https://local.example-client.com/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
If I make the same call with the Authorization Header using the Advanced Rest Client Chrome extension, it works correctly.
Accept:application/json <!----------- This one is */* when called from $http
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,nl;q=0.6
Authorization:Basic *** REMOVED *** <!----------- This one is missing when called from $http
Cache-Control:no-cache
Connection:keep-alive
Cookie: *** REMOVED ***
Host:www.example.com
Pragma:no-cache
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
One thing to note is that if I remove the Authorization header line (below), then the Accept header now appears:
//$http.defaults.headers.common.Authorization = 'Basic ************************';
Can anyone provide me any insight on what I may be missing here?

It's probably a problem with your CORS configuration. Authenticated requests require very specific configuration to work properly with CORS.
Make sure you're
Returning the Access-Control-Allow-Headers header to allow those headers
Returning the exact origin in Access-Control-Allow-Origin (not "*")
Setting withCredentials to true on the XHR (in Angular this can be set in the defaults just like the headers)
(I'm not entirely sure if the "Authorization" header is considered a "credential" if you set it by hand so the last two may or may not be required.)
The reason it works under Cordova is because Cordova doesn't implement origin restrictions for XHRs (they would be a bit pointless since your app doesn't have anything "local" to communicate with)

Related

500 Internal server error received on python get request, the same url works in browser

I am trying to open and download pdfs using python requests based on urls I get from an API. This works for many of the files, but for files stored at one specific site I get a 500 Internal Server error response. In the respone there is a simple html with only the text: Not Authenticated.
When I paste the same url in Chrome I get the pdf. However I can see a "503 - Failed to load resource" error in the console as it failed to load some icon. Can this be relevant somehow?
The url also works when I run it in Postman with no headers at all.
I have seemingly the same issue as described in this question:
python requests http response 500 (site can be reached in browser)
However the fix of adding User-Agent to the header of the request does not help. Can there be some other header data required, and is there any way of checking what request my Chrome browser sends?
Update: I logged what request Chrome is sending and copyed the header to my python request. Still the same error. I have tried with our without the same cookie.
Here is my code:
import requests
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'nb,en-GB;q=0.9,en-US;q=0.8,en;q=0.7',
'Connection': 'keep-alive',
'Cookie': 'JSESSIONID=a95b392a6d468e2188e73d2c296b; NSC_FS-NL-CET-XFC-IUUQ-8081=ffffffff3d9c37c545525d5f4f58455e445a4a4229a1; JSESSIONID=7b1dd39854eee82b2db41225150e',
'Host': url.split('/')[2],
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}
response = requests.get(url, headers=headers, verify=True)
I use Python 3.6.3
I found that I only get the error when I run the GET through requests. So I changed to using: urllib.request.urlopen(url)
More info about this approach here: Download file from web in Python 3

Cross Domain ajax OPTIONS error 403 (Django)

I'm developing some site aaa.com with django, which sends cross-domain ajax "GET" requests to receive json data from bbb.com which is also running on django and is using REST framework. At this point everything works pretty fine with adding crossDomain: true; withCredentials:true. And of course its configurated on server-side of aaa.com.
...-Allow-Credentials: true;
...-Allow-Origin: bbb.com
The main issue comes when aaa.com is trying to make PUT POST DELETE ajax requests.
According to CORS documentation:
[https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0], client side ajax request is correct, and
...-Allow-Headers, ...-Allow-Methods
is matched with
...-Request-Headers, ...-Request-Methods
so this request is not 'simple' and first of all browser sends preflight request from aaa.com to bbb.com to ask if some custom headers and methods are allowed.
Everything is OK But I'm still getting 403 Error. Here is the request/response:
General:
Request URL:http://bbb.com/api/someapipage/
Request Method:OPTIONS
Status Code:403 Forbidden
Remote Address:some ip:80
Response Headers:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:accept, content-type, x-csrftoken, x-requested-with
Access-Control-Allow-Methods:GET, POST, OPTIONS, HEAD, PUT, DELETE
Access-Control-Allow-Origin:http://aaa.com
Allow:GET, POST, HEAD, OPTIONS
Connection:Keep-Alive
Content-Language:en
Content-Type:application/json
Date:Mon, 04 Jul 2016 14:20:38 GMT
Keep-Alive:timeout=5, max=100
Server:gunicorn/19.6.0
Transfer-Encoding:chunked
Vary:Accept,Accept-Language,Cookie
X-Frame-Options:SAMEORIGIN
Request Headers:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,ru;q=0.6
Access-Control-Request-Headers:accept, content-type, x-csrftoken
Access-Control-Request-Method:POST
Connection:keep-alive
Host:aaa.com
Origin:http://aaa.com
Referer:http://aaa.com/
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
After week of tries to fix this issue I realised that server wants to Vary: Cookie on pre-flighted request which is impossible because cross-domain pre-flight request cannot contain cookie in its header.
I started finding some solution to this issue and found:
https://code.djangoproject.com/ticket/13217
"Enabling django.middleware.locale.LocaleMiddleware causes that django adds a 'Vary: Cookie' header to every reponse."
So localMiddleware adds header Vary: Cookie even in pre-flight OPTIONS response
There are lots of reccomendations to use djang-cors-header to fix some of this problems. But using this package function are equal to my settings on server-side.
I have also found pretty package: django-dont-vary-on which if installed can set decorators to turn off Vary:cookie, but in my case i need to turn off Vary:cookie only in OPTIONS response.
Im bit new to django and actually cannot even imagine what to do in this situation. Every my step is just like walking on a mine field.
Is there any solution or some alternatives?
You have to CORS whitelist your client to access the server.
In case their is a Cross-domain request, the request becomes preflighted if you use methods other than GET, HEAD or POST.
Also, if POST is used to send request data with a Content-Type other
than application/x-www-form-urlencoded, multipart/form-data, or
text/plain, it becomes preflighted.
Its the server that allows the cross-domain client request to be processed or deny it (default).
So if you have access to the server-side application, you could do the following to get the response.
On server-side
Install django-cors-headers on your server side and white list your client domain or IP (it is also port specific)
pip install django-cors-headers
In settings.py, add it in your INSTALLED_APPS
INSTALLED_APPS = (
...
'corsheaders',
...
)
Add the corsheaders.middleware.CorsMiddleware in MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'**corsheaders.middleware.CorsMiddleware**',
'django.middleware.common.CommonMiddleware',
....
)
and define a CORS whitelist
CORS_ORIGIN_WHITELIST = (
'aaa.com',
)
Now as you have added your client in the CORS whitelist, you will now be able to make a successful ajax request.

Facebook Oauth CORS error

I am using oauth2 to handle a user login via facebook. The error occurs when I call the authorization server in the golang api.
Here is the network error.
Fetch API cannot load https://www.facebook.com/dialog/oauth?client_id=1543358959292867&redirect_u…=email+public_profile&state=mUi4IpdY8yF5TNVVptMNNSn8IbVSZxJXTSEFM8Zg8LM%3D. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
network info (chrome)
Request URL:https://www.facebook.com/dialog/oauth?client_id=1543358959292867&redirect_uri=http%3A%2F%2Flocalhost%3A7001%2FFBLogin%2FCallback&response_type=code&scope=email+public_profile&state=lkmenB4FjNOShUQzL0Gpymi1xsvauaL7TawmUjCyvI4%3D
Request Method:GET
Status Code:302
Remote Address:[2a03:2880:f003:c1f:face:b00c:0:25de]:443
request headers
:authority:www.facebook.com
:method:GET
:path:/dialog/oauth?client_id=1543358959292867&redirect_uri=http%3A%2F%2Flocalhost%3A7001%2FFBLogin%2FCallback&response_type=code&scope=email+public_profile&state=KPbwnGWQoI7PHvwhJ_JvZ7RowPthjqpaDTgKVI5NHrM%3D
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, sdch
accept-language:en-US,en;q=0.8
origin:null
referer:http://localhost:3000/
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36
Javascript function that calls server api.
let loginUrl = "http://localhost:7001/FBLogin" //server url
let config = {
method: 'GET',
mode: 'cors',
}
fetch(loginUrl, config).then(response => {
...
}
Golang function that calls oauth authorization server (facebook).
func FBLogin(w http.ResponseWriter, r *http.Request) {
state, err := hashutil.GenerateRandomState()
logutil.Fatal(err)
url := config["fb"].AuthCodeURL(state)
logutil.OauthSessionLogger(state)
http.Redirect(w, r, url, 302)
}
I set the proper headers on the server side following this guide. Setting HTTP headers in Golang
I can't seem to find where the error comes from. (facebook API developer console, the callback headers in the server code, or the javascript initiating the call? I spent a lot of time changing the server headers but the error still persists as a CORS issue.
The origin in my request header is null, is that something to consider?
edit added no-cors mode result.
FBLogin 302 text/html SessionActions.js?524b:35 736 B 5 ms
oauth?client_id=154335&redirect_uri=http%3A%2F%2Flocalhost%3A7001%2FFBLogin%2FCallback&D
302 text/html
http://localhost:7001/FBLogin 611 B 57 ms
login.php?skip_api_login=1&api_key=154335 200
All three calls were successful, but was never redirected to the oauth page even when it said so. The response type was 'opaque' with a status 0.

The requested resource does not support http method 'OPTIONS'."

This is another CORS question. I have a weird issue.
I have an old application. i have access to inetpub but not the source code (only dlls and web.config).
So, before i make any POST call, there is a preflight call that is happening and somehow , the server is now allowing options to happen.
How do i make this work with just web.config or iis changes?
interestingly, Get call works. only post doesnt work.
I have added the following in Web.config of the api
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
in my test application, when i try to call the api, i am sending the following in the request headers
OPTIONS http://OldWebApiurl HTTP/1.1
Host: http://Oldwebapi.host
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://TestSite
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://testsite/page
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
How do i make this work with just web.config or iis changes?
I am afraid that this might not be possible with changes to those files only. For example if you are using ASP.NET Web API (which you seem to be using according to the tags used in your question) you might consult the following tutorial explaining the required changes you need to make to your source code in order to enable CORS.
So long story short, get the code of this web application from source control, add the config.EnableCors(); call to the bootstrapping section and decorate the controllers/actions that need to be accessible with CORS with the [EnableCors(...)] attribute. Then push back the changes you did in the source control, trigger a build and let the continuous delivery do the rest and deploy your changes to the target environment. Then you can enjoy CORS.
interestingly, Get call works. only post doesnt work.
That's perfectly normal, most common browsers simply do not make a pre-flight request for GET AJAX calls because those are considered safe - those are not supposed to modify any server side state so they are allowed.

prototypeJS Ajax call vanishes

I've got a problem with an Ajax request in my web project. Most of the time it works just fine but sometimes there is simply no request from the client (it does not show in wireshark), FireBug just shows the request marked red.
Project looks like the following:
Java Backend with JSPs, Client is using the Firefox Browser
The request is done via prototypejs using the Ajax Updater function. I can debug the request preparation via firebug until the Ajax Update function fires the request but then no request is listed in my wireshark output (although all other request are listed just fine).
So I have a (sometimes) vanished Ajax request with no error and no clue where to look :( Any help would be much appreciated.
Request:
[...]/ajax/gruppe/loadTreeList.do?ajax=true&tstamp=645&context=GRUPPE&level=0&it‌​emid=0
RequestHeader:
Accept text/javascript, text/html, application/xml, text/xml, /
Accept-Encoding gzip, deflate
Accept-Language de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Connection keep-alive
Cookie JSESSIONID=326D8AEAAFD254760CEC8D050734807E
Host localhost:8080
Referer [...]/domain/druck/gruppe.do
User-Agent Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0
X-Prototype-Version 1.7.1
X-Requested-With XMLHttpRequest
There is no response.

Resources