27

I would like to know why my asp.net application will not add the header to my post when it is named 'Authorization' but will work fine when I change one character, say "Authorizations". In documentation for other sites they always use the name "Authorization" so I would like to as well and at this point I just want to under stand why.

I have read a few topics about this but have not found any logical reason why.

Here is my code below:

string fileName = "c:\\xyz.xml";
string uri = "http://myserver/Default.aspx";
req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "text/xml";
byte[] authBytes = Encoding.UTF8.GetBytes("DDSServices:jCole2011".ToCharArray());
req.Headers.Add("Authorization", "BASIC " + Convert.ToBase64String(authBytes) );
req.Headers.Add("test", "test");
UTF8Encoding encoder = new UTF8Encoding();
byte[] data = encoder.GetBytes(this.GetTextFromXMLFile(fileName));
req.ContentLength = data.Length;
Stream reqStream = req.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
req.Headers.Add("Authorization", "BASIC" + Convert.ToBase64String(authBytes));
System.Net.WebResponse response = req.GetResponse();
System.IO.StreamReader reader = new StreamReader(response.GetResponseStream());
string str = reader.ReadToEnd();

The other annoying this is when i add the watched variable through fiddler it works fine.

0

3 Answers 3

43

I was ran into a question how to add Authentication/Credentials to the headers. I found the solution in the following way.

string _auth = string.Format("{0}:{1}", "myUser","myPwd");
string _enc = Convert.ToBase64String(Encoding.ASCII.GetBytes(_auth));
string _cred = string.Format("{0} {1}", "Basic", _enc);
req.Headers[HttpRequestHeader.Authorization] = _cred;

Which gave me those headers I want (pasted Wireshark descriptions),

Authorization: Basic bXlVc2VyOm15UHdk\r\n
Credentials: myUser:myPwd

Sign up to request clarification or add additional context in comments.

2 Comments

So how do you know for sure the encoding to use is ASCII?
Nice point. The choosen encoding looks like a possible "hard to find"-source for bugs. I add the link stackoverflow.com/questions/7242316/… for readers to find more information of how to decide.
11

For HTTP Basic Authorization, you should be using the Credentials property.

req.Credentials = new NetworkCredential("DDSServices", "jCole2011");

This should do what you want. Rather than setting the Authorization header.

8 Comments

or is there a logical reason? A very large third party company that we work with has documentation with their authorization in the same manner, so I would like to know the reason.
It is much better to use the NetworkCredential approach as Will suggests. However, your approach should also work fine, although I dont understand why you are doing it twice (one before call to GetRquestStream, and once after. You should do it jsut once before y ou call GetRequestStream. If it still doesnt work, get a trace log. Instructions at ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html
Can you tell me why it is better? Or where i can read about why it is better? To me it seems NetworkCredentials would be tied in with ad or forms authentication, I would rather the connection be through anonymous, then just verify. Either way though can someone just tell me why? I almost don't care about what at this point.
NetworkCredential only sends the Authentication header after a 401 is received. This is probably not what you want... Use the old fashion way: var credentialBuffer = new UTF8Encoding().GetBytes(aUserName + ":" + aPassword); request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
@WillHughes That's not true. I tried to use the PreAuthenticate=true but it was not working. The link you posted verifies that you need to catch the 401 the first time. "Property Value Type: System.Boolean true to send an HTTP Authorization header with requests after authentication has taken place; otherwise, false. The default is false."
|
3

NetworkCredential is a good solution but the site you are calling has to handle an unauthorized with a 401 AND a WWW-Authenticate header in the response.

Client:

request.Credentials = new CredentialCache {{aUri, "Basic", new NetworkCredential(aUserName, aPassword)}};

Server:

Response.ClearContent();
Response.StatusCode = 401;
Response.AddHeader("WWW-Authenticate", "Basic");
Response.End();

This will result in 2 hits to the server. The initial call will go to the server without credentials. When the server responds with a 401 AND the WWW-Authenticate header (with the type of authentication required), the request will be resent with the credentials in the request.

1 Comment

This is true, but sending back 401 Unauthorized, and the WWW-Authenticate header is part of the HTTP Spec. If you want to force sending the header on the first request, you can do so through the PreAuthenticate method. In Addition - IIS automatically handles sending back this response, as do other well-written HTTP servers such as Apache. It's how browsers know to display the password prompt dialog.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.