how to set authorization header with android's httpURLconnection
Asked Answered
S

1

7

I am attempting to connect to my server using basic authentication, but when I set the Authorization header, it causes getInputStream to throw a fileNotFound exception.

Here is the relevant code:

        URL url = new URL(myurl);
        //set up the connection
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000);//this is in milliseconds
        conn.setConnectTimeout(15000);//this is in milliseconds
        String authHeader = getAuthHeader(userID,pass);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.setRequestProperty("authorization", authHeader);
        //starts the query
        conn.connect();
        int response = conn.getResponseCode();
        is = conn.getInputStream(); //throws the fileNotFound exception

Here is the thrown exception:

java.io.FileNotFoundException: http://<myIPaddress>/login/

Weirdly enough, I have found that the fileNotFound exception is only thrown if I try to set the request property to "authorization" or "Authorization" or any variation of that word. it is not thrown if I set it to "content-type" or "authosodifjsodfjs" (a random string), as here:

conn.setRequestProperty("content-type",authHeader)//no exception thrown
conn.setRequestProperty("authosodifjsodfjs",authHeader)//no exception thrown

If I don't set this header, I am able to connect to the server with this code and get the proper access-denied message that I am expecting. I am also able to connect to the server and login properly if I use python's "requests" module, so it is not a problem with the server.

so my question is as follows:

1) what, if anything, am I doing wrong when setting the request property as "authorization"? how do I set the auth header properly?

2) if this is a bug with HttpURLConnection, how do I file a bug report?

Thank you.

edit: it was recommended to switch from:

conn.setRequestProperty("Authorization", authHeader);

to:

conn.addRequestProperty("Authorization", authHeader);

This did not fix the problem. It is still throwing the same exception.

EDIT: still not sure why "Authorization" and "authorization" are causing fileNotFounExceptions, but using all caps seems to work properly. here is the shiny new working code:

conn.setRequestProperty("AUTHORIZATION",authHeader);

so it looks like it needs to be all caps. "HTTP_" will be automattically added to the front of this header, so the header that the server will see is "HTTP_AUTHORIZATION", which is what it should be.

Stefan answered 21/12, 2015 at 18:59 Comment(2)
What does getAuthHeader(String, String) return?Shuntwound
private String getAuthHeader(String ID, String pass){ String encoded = Base64.encodeToString((ID + ":" + pass).getBytes(), Base64.NO_WRAP); String returnThis = "Basic " + encoded; return returnThis; }Stefan
D
14

Here is part of my OAuth code which sets Authorization header:

httpUrlConnection.setUseCaches(false);
httpUrlConnection.setRequestProperty("User-Agent", "MyAgent");
httpUrlConnection.setConnectTimeout(30000);
httpUrlConnection.setReadTimeout(30000);

String baseAuthStr = APIKEY + ":" + APISECRET;
httpUrlConnection.addRequestProperty("Authorization", "Basic " + baseAuthStr);
httpUrlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

httpUrlConnection.connect();
Divest answered 21/12, 2015 at 19:11 Comment(7)
thank you for responding. do you have a second type of connection set up? you are adding a request property to "urlConnection" but are connectiong with "httpUrlConnection"..?Stefan
@JoeRyan httpUrlConnection is the same as your connDivest
Thank you Marcin. I switched from "setRequestProperty()" to "addRequestProperty()", like your code, but unfortunately it did not solve anything.Stefan
@JoeRyan I suppose you should check response before calling getInputStream - and call it only with response code == 200. If its different then use getErrorStream. At least thats how I do in my code.Divest
If I set the auth header , I get response code 500 (internal server error) using android. If I do the same thing using python requests, I get response code 200.... so for some reason it looks like setting the header in Android is changing which response I get from the server. If I don't set the headers at all, I get the same response code if I use android or python.Stefan
@JoeRyan I such case I would use Fiddler2 (under windows) to compare what goes in TCP packets exactly under python version versus android version. Under android you can easily setup proxy for wifi connection which will route all your traffic over a sniffer application. Dont start with finding bugs in Android.Divest
so I tried setting the header directly to "HTTP_AUTHORIZATION", which didn't work ,but than looked at the headers the server was getting and it turns out android was just prepending "HTTP_" to the headers... anyways, I changed the header to "AUTHORIZATION" (all caps) and it worked, magically. I'll credit you with the answer. thanksStefan

© 2022 - 2024 — McMap. All rights reserved.