Implement Digest authentication via HttpWebRequest in C#How to parse HttpWebResponse.Headers.Keys for a Set-Cookie session id returnedHow can I do digest authentication with HttpWebRequest?The definitive guide to form-based website authenticationWhat is the difference between String and string in C#?Cast int to enum in C#How do I enumerate an enum in C#?What are the correct version numbers for C#?disable HTTP digest Authentication Window in AIRImport Login and Password from Digest access authenticationDigest md5 response generationDigest Auth - encoding of email address usernameDigest authentication with spring security: 401 recieved as expected but with two WWW-Authenticate headers
Confused about the answers to two logic problems
Write an interpreter for *
Find y in this equation
How to avoid the "need" to learn more before conducting research?
What costs less energy? Roll or Yaw?
How are you supposed to know the strumming pattern for a song from the "chord sheet music"?
Understanding the point of a kölsche Witz
What are the conventions for transcribing Semitic languages into Greek?
Am I overreacting to my team leader's unethical requests?
Why do funding agencies like the NSF not publish accepted grants?
Why isn’t SHA-3 in wider use?
Word or idiom defining something barely functional
Dropdowns & Chevrons for Right to Left languages
Te-form and かつ and も?
Withdrew when Jimmy met up with Heath
What is my malfunctioning AI harvesting from humans?
How is this kind of structure made?
The cat ate your input again!
Not going forward with internship interview process
Why are Gatwick's runways too close together?
Does this Foo machine halt?
In SQL Server, why does backward scan of clustered index cannot use parallelism?
Why is transplanting a specific intact brain impossible if it is generally possible?
Is refreshing multiple times a test case for web applications?
Implement Digest authentication via HttpWebRequest in C#
How to parse HttpWebResponse.Headers.Keys for a Set-Cookie session id returnedHow can I do digest authentication with HttpWebRequest?The definitive guide to form-based website authenticationWhat is the difference between String and string in C#?Cast int to enum in C#How do I enumerate an enum in C#?What are the correct version numbers for C#?disable HTTP digest Authentication Window in AIRImport Login and Password from Digest access authenticationDigest md5 response generationDigest Auth - encoding of email address usernameDigest authentication with spring security: 401 recieved as expected but with two WWW-Authenticate headers
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Does anyone know how to screen scrape web-sites that use digest http authentication?
I use code like this:
var request = (HttpWebRequest)WebRequest.Create(SiteUrl);
request.Credentials=new NetworkCredential(Login, Password)
I'm able to access the site's mainpage, but when I try to surf to any other pages (using another request with the same credentials) I get "HTTP/1.1 400 Bad Request" error.
I used Fiddler to compare requests of my C# application with Mozilla Firefox requests.
2 URLs that I try to access are:
https://mysiteurl/forum/index.php
https://mysiteurl/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203
Here are 2 requests () of my C# app:
Authorization: Digest username="xxx",realm="abc",nonce="NXa26+NjBAA=747dfd1776c9d585bd388377ef3160f1ff265429",uri="/forum/index.php",algorithm="MD5",cnonce="89179bf17dd27785aa1c88ad976817c9",nc=00000001,qop="auth",response="3088821620d9cbbf71e775fddbacfb6d"
Authorization: Digest username="xxx",realm="abc",nonce="1h7T6+NjBAA=4fed4d804d0edcb54bf4c2f912246330d96afa76",uri="/forum/viewforum.php",algorithm="MD5",cnonce="bb990b0516a371549401c0289fbacc7c",nc=00000001,qop="auth",response="1ddb95a45fd7ea8dbefd37a2db705e3a"
And that's what Firefox sending to the server:
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/", algorithm=MD5, response="33f29dcc5d70b61be18eaddfca9bd601", qop=auth, nc=00000001, cnonce="ab96bbe39d8d776d"
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203", algorithm=MD5, response="a996dae9368a79d49f2f29ea7a327cd5", qop=auth, nc=00000002, cnonce="e233ae90908860e1"
So in my app I have different values in "nonce" field while in Firefox this field is the same. On the other hand I have same values in "nc" field while Firefox increments this field.
Also when my app tries to access site pages in Fiddler i can see that it always gets response "HTTP/1.1 401 Authorization Required", while Firefox authorizes only once. I've tried to set request.PreAuthenticate = true; but it seems to have no effect...
My question is: how to properly implement digest authentication using C#? Are there any standard methods or do I have to do it from scratch? Thanks in advance.
c# authentication httpwebrequest digest
add a comment |
Does anyone know how to screen scrape web-sites that use digest http authentication?
I use code like this:
var request = (HttpWebRequest)WebRequest.Create(SiteUrl);
request.Credentials=new NetworkCredential(Login, Password)
I'm able to access the site's mainpage, but when I try to surf to any other pages (using another request with the same credentials) I get "HTTP/1.1 400 Bad Request" error.
I used Fiddler to compare requests of my C# application with Mozilla Firefox requests.
2 URLs that I try to access are:
https://mysiteurl/forum/index.php
https://mysiteurl/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203
Here are 2 requests () of my C# app:
Authorization: Digest username="xxx",realm="abc",nonce="NXa26+NjBAA=747dfd1776c9d585bd388377ef3160f1ff265429",uri="/forum/index.php",algorithm="MD5",cnonce="89179bf17dd27785aa1c88ad976817c9",nc=00000001,qop="auth",response="3088821620d9cbbf71e775fddbacfb6d"
Authorization: Digest username="xxx",realm="abc",nonce="1h7T6+NjBAA=4fed4d804d0edcb54bf4c2f912246330d96afa76",uri="/forum/viewforum.php",algorithm="MD5",cnonce="bb990b0516a371549401c0289fbacc7c",nc=00000001,qop="auth",response="1ddb95a45fd7ea8dbefd37a2db705e3a"
And that's what Firefox sending to the server:
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/", algorithm=MD5, response="33f29dcc5d70b61be18eaddfca9bd601", qop=auth, nc=00000001, cnonce="ab96bbe39d8d776d"
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203", algorithm=MD5, response="a996dae9368a79d49f2f29ea7a327cd5", qop=auth, nc=00000002, cnonce="e233ae90908860e1"
So in my app I have different values in "nonce" field while in Firefox this field is the same. On the other hand I have same values in "nc" field while Firefox increments this field.
Also when my app tries to access site pages in Fiddler i can see that it always gets response "HTTP/1.1 401 Authorization Required", while Firefox authorizes only once. I've tried to set request.PreAuthenticate = true; but it seems to have no effect...
My question is: how to properly implement digest authentication using C#? Are there any standard methods or do I have to do it from scratch? Thanks in advance.
c# authentication httpwebrequest digest
add a comment |
Does anyone know how to screen scrape web-sites that use digest http authentication?
I use code like this:
var request = (HttpWebRequest)WebRequest.Create(SiteUrl);
request.Credentials=new NetworkCredential(Login, Password)
I'm able to access the site's mainpage, but when I try to surf to any other pages (using another request with the same credentials) I get "HTTP/1.1 400 Bad Request" error.
I used Fiddler to compare requests of my C# application with Mozilla Firefox requests.
2 URLs that I try to access are:
https://mysiteurl/forum/index.php
https://mysiteurl/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203
Here are 2 requests () of my C# app:
Authorization: Digest username="xxx",realm="abc",nonce="NXa26+NjBAA=747dfd1776c9d585bd388377ef3160f1ff265429",uri="/forum/index.php",algorithm="MD5",cnonce="89179bf17dd27785aa1c88ad976817c9",nc=00000001,qop="auth",response="3088821620d9cbbf71e775fddbacfb6d"
Authorization: Digest username="xxx",realm="abc",nonce="1h7T6+NjBAA=4fed4d804d0edcb54bf4c2f912246330d96afa76",uri="/forum/viewforum.php",algorithm="MD5",cnonce="bb990b0516a371549401c0289fbacc7c",nc=00000001,qop="auth",response="1ddb95a45fd7ea8dbefd37a2db705e3a"
And that's what Firefox sending to the server:
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/", algorithm=MD5, response="33f29dcc5d70b61be18eaddfca9bd601", qop=auth, nc=00000001, cnonce="ab96bbe39d8d776d"
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203", algorithm=MD5, response="a996dae9368a79d49f2f29ea7a327cd5", qop=auth, nc=00000002, cnonce="e233ae90908860e1"
So in my app I have different values in "nonce" field while in Firefox this field is the same. On the other hand I have same values in "nc" field while Firefox increments this field.
Also when my app tries to access site pages in Fiddler i can see that it always gets response "HTTP/1.1 401 Authorization Required", while Firefox authorizes only once. I've tried to set request.PreAuthenticate = true; but it seems to have no effect...
My question is: how to properly implement digest authentication using C#? Are there any standard methods or do I have to do it from scratch? Thanks in advance.
c# authentication httpwebrequest digest
Does anyone know how to screen scrape web-sites that use digest http authentication?
I use code like this:
var request = (HttpWebRequest)WebRequest.Create(SiteUrl);
request.Credentials=new NetworkCredential(Login, Password)
I'm able to access the site's mainpage, but when I try to surf to any other pages (using another request with the same credentials) I get "HTTP/1.1 400 Bad Request" error.
I used Fiddler to compare requests of my C# application with Mozilla Firefox requests.
2 URLs that I try to access are:
https://mysiteurl/forum/index.php
https://mysiteurl/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203
Here are 2 requests () of my C# app:
Authorization: Digest username="xxx",realm="abc",nonce="NXa26+NjBAA=747dfd1776c9d585bd388377ef3160f1ff265429",uri="/forum/index.php",algorithm="MD5",cnonce="89179bf17dd27785aa1c88ad976817c9",nc=00000001,qop="auth",response="3088821620d9cbbf71e775fddbacfb6d"
Authorization: Digest username="xxx",realm="abc",nonce="1h7T6+NjBAA=4fed4d804d0edcb54bf4c2f912246330d96afa76",uri="/forum/viewforum.php",algorithm="MD5",cnonce="bb990b0516a371549401c0289fbacc7c",nc=00000001,qop="auth",response="1ddb95a45fd7ea8dbefd37a2db705e3a"
And that's what Firefox sending to the server:
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/", algorithm=MD5, response="33f29dcc5d70b61be18eaddfca9bd601", qop=auth, nc=00000001, cnonce="ab96bbe39d8d776d"
Authorization: Digest username="xxx", realm="abc", nonce="T9ICNeRjBAA=4fbb28d42db044e182116ac27176e81d067a313c", uri="/forum/viewforum.php?f=4&sid=d104363e563968b4e4c07e04f4a15203", algorithm=MD5, response="a996dae9368a79d49f2f29ea7a327cd5", qop=auth, nc=00000002, cnonce="e233ae90908860e1"
So in my app I have different values in "nonce" field while in Firefox this field is the same. On the other hand I have same values in "nc" field while Firefox increments this field.
Also when my app tries to access site pages in Fiddler i can see that it always gets response "HTTP/1.1 401 Authorization Required", while Firefox authorizes only once. I've tried to set request.PreAuthenticate = true; but it seems to have no effect...
My question is: how to properly implement digest authentication using C#? Are there any standard methods or do I have to do it from scratch? Thanks in advance.
c# authentication httpwebrequest digest
c# authentication httpwebrequest digest
asked Feb 27 '09 at 11:01
RaTT
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
Create a class Digest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
namespace NUI
public class DigestAuthFixer
private static string _host;
private static string _user;
private static string _password;
private static string _realm;
private static string _nonce;
private static string _qop;
private static string _cnonce;
private static DateTime _cnonceDate;
private static int _nc;
public DigestAuthFixer(string host, string user, string password)
// TODO: Complete member initialization
_host = host;
_user = user;
_password = password;
private string CalculateMd5Hash(
string input)
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = MD5.Create().ComputeHash(inputBytes);
var sb = new StringBuilder();
foreach (var b in hash)
sb.Append(b.ToString("x2"));
return sb.ToString();
private string GrabHeaderVar(
string varName,
string header)
var regHeader = new Regex(string.Format(@"0=""([^""]*)""", varName));
var matchHeader = regHeader.Match(header);
if (matchHeader.Success)
return matchHeader.Groups[1].Value;
throw new ApplicationException(string.Format("Header 0 not found", varName));
private string GetDigestHeader(
string dir)
_nc = _nc + 1;
var ha1 = CalculateMd5Hash(string.Format("0:1:2", _user, _realm, _password));
var ha2 = CalculateMd5Hash(string.Format("0:1", "GET", dir));
var digestResponse =
CalculateMd5Hash(string.Format("0:1:2:00000000:3:4:5", ha1, _nonce, _nc, _cnonce, _qop, ha2));
return string.Format("Digest username="0", realm="1", nonce="2", uri="3", " +
"algorithm=MD5, response="4", qop=5, nc=6:00000000, cnonce="7"",
_user, _realm, _nonce, dir, digestResponse, _qop, _nc, _cnonce);
public string GrabResponse(
string dir)
var url = _host + dir;
var uri = new Uri(url);
var request = (HttpWebRequest)WebRequest.Create(uri);
// If we've got a recent Auth header, re-use it!
if (!string.IsNullOrEmpty(_cnonce) &&
DateTime.Now.Subtract(_cnonceDate).TotalHours < 1.0)
request.Headers.Add("Authorization", GetDigestHeader(dir));
HttpWebResponse response;
try
response = (HttpWebResponse)request.GetResponse();
catch (WebException ex)
// Try to fix a 401 exception by adding a Authorization header
if (ex.Response == null
var reader = new StreamReader(response.GetResponseStream());
return reader.ReadToEnd();
Now in your application, you can use the following code:
DigestAuthFixer digest = new DigestAuthFixer(url, username, password);
string strReturn = digest.GrabResponse(url);
+1 Just used this to connect to my router, but it returns a Set-Cookie header, so you need to add the cookies to all subsequent requests if you happen upon same situation. p.s. to parse cookies you can use this answer: stackoverflow.com/a/1055883/289992
– bottlenecked
Jan 25 '14 at 10:07
interesting. thanks for the suggestion
– kitwalker
Jan 25 '14 at 21:22
I know this is an ancient post, but if anyone like me stumbles over this problem and would like to use kitwalkers solution, be advised that the usage example above is incorrect. The DigestAuthFixer constructor and the GrabResponse method should not have the full URL as first parameter. Instead constructor should only have the host part, and GrabResponse only the rest of the URL (without host).
– TheRoadrunner
Jul 15 '18 at 7:01
add a comment |
This article from 4GuysFromRolla appears to be what you are looking for:
http://www.4guysfromrolla.com/articles/102605-1.aspx
Unfortunately this does not talk about dealing with "nonce" or similar. It is implied that Digest, but how can it know the correct nonce of the previous request without using the "auto auth"?
– user166390
Sep 21 '11 at 5:02
add a comment |
I'm currently observing the same issue, though the web server I'm testing this against is my own. The server logs show:
Digest: uri mismatch - </var/path/some.jpg> does not match request-uri
</var/path/some.jpg?parameter=123456789>
I tried removing the arguments from the URL (as that seemed to be what's different), but the error still occurred just like before.
My conclusion is that the URL arguments have to be included in the digest hash as well and that the HttpWebRequest
is for some reason removing it.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f594323%2fimplement-digest-authentication-via-httpwebrequest-in-c-sharp%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Create a class Digest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
namespace NUI
public class DigestAuthFixer
private static string _host;
private static string _user;
private static string _password;
private static string _realm;
private static string _nonce;
private static string _qop;
private static string _cnonce;
private static DateTime _cnonceDate;
private static int _nc;
public DigestAuthFixer(string host, string user, string password)
// TODO: Complete member initialization
_host = host;
_user = user;
_password = password;
private string CalculateMd5Hash(
string input)
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = MD5.Create().ComputeHash(inputBytes);
var sb = new StringBuilder();
foreach (var b in hash)
sb.Append(b.ToString("x2"));
return sb.ToString();
private string GrabHeaderVar(
string varName,
string header)
var regHeader = new Regex(string.Format(@"0=""([^""]*)""", varName));
var matchHeader = regHeader.Match(header);
if (matchHeader.Success)
return matchHeader.Groups[1].Value;
throw new ApplicationException(string.Format("Header 0 not found", varName));
private string GetDigestHeader(
string dir)
_nc = _nc + 1;
var ha1 = CalculateMd5Hash(string.Format("0:1:2", _user, _realm, _password));
var ha2 = CalculateMd5Hash(string.Format("0:1", "GET", dir));
var digestResponse =
CalculateMd5Hash(string.Format("0:1:2:00000000:3:4:5", ha1, _nonce, _nc, _cnonce, _qop, ha2));
return string.Format("Digest username="0", realm="1", nonce="2", uri="3", " +
"algorithm=MD5, response="4", qop=5, nc=6:00000000, cnonce="7"",
_user, _realm, _nonce, dir, digestResponse, _qop, _nc, _cnonce);
public string GrabResponse(
string dir)
var url = _host + dir;
var uri = new Uri(url);
var request = (HttpWebRequest)WebRequest.Create(uri);
// If we've got a recent Auth header, re-use it!
if (!string.IsNullOrEmpty(_cnonce) &&
DateTime.Now.Subtract(_cnonceDate).TotalHours < 1.0)
request.Headers.Add("Authorization", GetDigestHeader(dir));
HttpWebResponse response;
try
response = (HttpWebResponse)request.GetResponse();
catch (WebException ex)
// Try to fix a 401 exception by adding a Authorization header
if (ex.Response == null
var reader = new StreamReader(response.GetResponseStream());
return reader.ReadToEnd();
Now in your application, you can use the following code:
DigestAuthFixer digest = new DigestAuthFixer(url, username, password);
string strReturn = digest.GrabResponse(url);
+1 Just used this to connect to my router, but it returns a Set-Cookie header, so you need to add the cookies to all subsequent requests if you happen upon same situation. p.s. to parse cookies you can use this answer: stackoverflow.com/a/1055883/289992
– bottlenecked
Jan 25 '14 at 10:07
interesting. thanks for the suggestion
– kitwalker
Jan 25 '14 at 21:22
I know this is an ancient post, but if anyone like me stumbles over this problem and would like to use kitwalkers solution, be advised that the usage example above is incorrect. The DigestAuthFixer constructor and the GrabResponse method should not have the full URL as first parameter. Instead constructor should only have the host part, and GrabResponse only the rest of the URL (without host).
– TheRoadrunner
Jul 15 '18 at 7:01
add a comment |
Create a class Digest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
namespace NUI
public class DigestAuthFixer
private static string _host;
private static string _user;
private static string _password;
private static string _realm;
private static string _nonce;
private static string _qop;
private static string _cnonce;
private static DateTime _cnonceDate;
private static int _nc;
public DigestAuthFixer(string host, string user, string password)
// TODO: Complete member initialization
_host = host;
_user = user;
_password = password;
private string CalculateMd5Hash(
string input)
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = MD5.Create().ComputeHash(inputBytes);
var sb = new StringBuilder();
foreach (var b in hash)
sb.Append(b.ToString("x2"));
return sb.ToString();
private string GrabHeaderVar(
string varName,
string header)
var regHeader = new Regex(string.Format(@"0=""([^""]*)""", varName));
var matchHeader = regHeader.Match(header);
if (matchHeader.Success)
return matchHeader.Groups[1].Value;
throw new ApplicationException(string.Format("Header 0 not found", varName));
private string GetDigestHeader(
string dir)
_nc = _nc + 1;
var ha1 = CalculateMd5Hash(string.Format("0:1:2", _user, _realm, _password));
var ha2 = CalculateMd5Hash(string.Format("0:1", "GET", dir));
var digestResponse =
CalculateMd5Hash(string.Format("0:1:2:00000000:3:4:5", ha1, _nonce, _nc, _cnonce, _qop, ha2));
return string.Format("Digest username="0", realm="1", nonce="2", uri="3", " +
"algorithm=MD5, response="4", qop=5, nc=6:00000000, cnonce="7"",
_user, _realm, _nonce, dir, digestResponse, _qop, _nc, _cnonce);
public string GrabResponse(
string dir)
var url = _host + dir;
var uri = new Uri(url);
var request = (HttpWebRequest)WebRequest.Create(uri);
// If we've got a recent Auth header, re-use it!
if (!string.IsNullOrEmpty(_cnonce) &&
DateTime.Now.Subtract(_cnonceDate).TotalHours < 1.0)
request.Headers.Add("Authorization", GetDigestHeader(dir));
HttpWebResponse response;
try
response = (HttpWebResponse)request.GetResponse();
catch (WebException ex)
// Try to fix a 401 exception by adding a Authorization header
if (ex.Response == null
var reader = new StreamReader(response.GetResponseStream());
return reader.ReadToEnd();
Now in your application, you can use the following code:
DigestAuthFixer digest = new DigestAuthFixer(url, username, password);
string strReturn = digest.GrabResponse(url);
+1 Just used this to connect to my router, but it returns a Set-Cookie header, so you need to add the cookies to all subsequent requests if you happen upon same situation. p.s. to parse cookies you can use this answer: stackoverflow.com/a/1055883/289992
– bottlenecked
Jan 25 '14 at 10:07
interesting. thanks for the suggestion
– kitwalker
Jan 25 '14 at 21:22
I know this is an ancient post, but if anyone like me stumbles over this problem and would like to use kitwalkers solution, be advised that the usage example above is incorrect. The DigestAuthFixer constructor and the GrabResponse method should not have the full URL as first parameter. Instead constructor should only have the host part, and GrabResponse only the rest of the URL (without host).
– TheRoadrunner
Jul 15 '18 at 7:01
add a comment |
Create a class Digest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
namespace NUI
public class DigestAuthFixer
private static string _host;
private static string _user;
private static string _password;
private static string _realm;
private static string _nonce;
private static string _qop;
private static string _cnonce;
private static DateTime _cnonceDate;
private static int _nc;
public DigestAuthFixer(string host, string user, string password)
// TODO: Complete member initialization
_host = host;
_user = user;
_password = password;
private string CalculateMd5Hash(
string input)
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = MD5.Create().ComputeHash(inputBytes);
var sb = new StringBuilder();
foreach (var b in hash)
sb.Append(b.ToString("x2"));
return sb.ToString();
private string GrabHeaderVar(
string varName,
string header)
var regHeader = new Regex(string.Format(@"0=""([^""]*)""", varName));
var matchHeader = regHeader.Match(header);
if (matchHeader.Success)
return matchHeader.Groups[1].Value;
throw new ApplicationException(string.Format("Header 0 not found", varName));
private string GetDigestHeader(
string dir)
_nc = _nc + 1;
var ha1 = CalculateMd5Hash(string.Format("0:1:2", _user, _realm, _password));
var ha2 = CalculateMd5Hash(string.Format("0:1", "GET", dir));
var digestResponse =
CalculateMd5Hash(string.Format("0:1:2:00000000:3:4:5", ha1, _nonce, _nc, _cnonce, _qop, ha2));
return string.Format("Digest username="0", realm="1", nonce="2", uri="3", " +
"algorithm=MD5, response="4", qop=5, nc=6:00000000, cnonce="7"",
_user, _realm, _nonce, dir, digestResponse, _qop, _nc, _cnonce);
public string GrabResponse(
string dir)
var url = _host + dir;
var uri = new Uri(url);
var request = (HttpWebRequest)WebRequest.Create(uri);
// If we've got a recent Auth header, re-use it!
if (!string.IsNullOrEmpty(_cnonce) &&
DateTime.Now.Subtract(_cnonceDate).TotalHours < 1.0)
request.Headers.Add("Authorization", GetDigestHeader(dir));
HttpWebResponse response;
try
response = (HttpWebResponse)request.GetResponse();
catch (WebException ex)
// Try to fix a 401 exception by adding a Authorization header
if (ex.Response == null
var reader = new StreamReader(response.GetResponseStream());
return reader.ReadToEnd();
Now in your application, you can use the following code:
DigestAuthFixer digest = new DigestAuthFixer(url, username, password);
string strReturn = digest.GrabResponse(url);
Create a class Digest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Net;
using System.IO;
namespace NUI
public class DigestAuthFixer
private static string _host;
private static string _user;
private static string _password;
private static string _realm;
private static string _nonce;
private static string _qop;
private static string _cnonce;
private static DateTime _cnonceDate;
private static int _nc;
public DigestAuthFixer(string host, string user, string password)
// TODO: Complete member initialization
_host = host;
_user = user;
_password = password;
private string CalculateMd5Hash(
string input)
var inputBytes = Encoding.ASCII.GetBytes(input);
var hash = MD5.Create().ComputeHash(inputBytes);
var sb = new StringBuilder();
foreach (var b in hash)
sb.Append(b.ToString("x2"));
return sb.ToString();
private string GrabHeaderVar(
string varName,
string header)
var regHeader = new Regex(string.Format(@"0=""([^""]*)""", varName));
var matchHeader = regHeader.Match(header);
if (matchHeader.Success)
return matchHeader.Groups[1].Value;
throw new ApplicationException(string.Format("Header 0 not found", varName));
private string GetDigestHeader(
string dir)
_nc = _nc + 1;
var ha1 = CalculateMd5Hash(string.Format("0:1:2", _user, _realm, _password));
var ha2 = CalculateMd5Hash(string.Format("0:1", "GET", dir));
var digestResponse =
CalculateMd5Hash(string.Format("0:1:2:00000000:3:4:5", ha1, _nonce, _nc, _cnonce, _qop, ha2));
return string.Format("Digest username="0", realm="1", nonce="2", uri="3", " +
"algorithm=MD5, response="4", qop=5, nc=6:00000000, cnonce="7"",
_user, _realm, _nonce, dir, digestResponse, _qop, _nc, _cnonce);
public string GrabResponse(
string dir)
var url = _host + dir;
var uri = new Uri(url);
var request = (HttpWebRequest)WebRequest.Create(uri);
// If we've got a recent Auth header, re-use it!
if (!string.IsNullOrEmpty(_cnonce) &&
DateTime.Now.Subtract(_cnonceDate).TotalHours < 1.0)
request.Headers.Add("Authorization", GetDigestHeader(dir));
HttpWebResponse response;
try
response = (HttpWebResponse)request.GetResponse();
catch (WebException ex)
// Try to fix a 401 exception by adding a Authorization header
if (ex.Response == null
var reader = new StreamReader(response.GetResponseStream());
return reader.ReadToEnd();
Now in your application, you can use the following code:
DigestAuthFixer digest = new DigestAuthFixer(url, username, password);
string strReturn = digest.GrabResponse(url);
answered Nov 21 '12 at 19:39
kitwalkerkitwalker
6279 silver badges25 bronze badges
6279 silver badges25 bronze badges
+1 Just used this to connect to my router, but it returns a Set-Cookie header, so you need to add the cookies to all subsequent requests if you happen upon same situation. p.s. to parse cookies you can use this answer: stackoverflow.com/a/1055883/289992
– bottlenecked
Jan 25 '14 at 10:07
interesting. thanks for the suggestion
– kitwalker
Jan 25 '14 at 21:22
I know this is an ancient post, but if anyone like me stumbles over this problem and would like to use kitwalkers solution, be advised that the usage example above is incorrect. The DigestAuthFixer constructor and the GrabResponse method should not have the full URL as first parameter. Instead constructor should only have the host part, and GrabResponse only the rest of the URL (without host).
– TheRoadrunner
Jul 15 '18 at 7:01
add a comment |
+1 Just used this to connect to my router, but it returns a Set-Cookie header, so you need to add the cookies to all subsequent requests if you happen upon same situation. p.s. to parse cookies you can use this answer: stackoverflow.com/a/1055883/289992
– bottlenecked
Jan 25 '14 at 10:07
interesting. thanks for the suggestion
– kitwalker
Jan 25 '14 at 21:22
I know this is an ancient post, but if anyone like me stumbles over this problem and would like to use kitwalkers solution, be advised that the usage example above is incorrect. The DigestAuthFixer constructor and the GrabResponse method should not have the full URL as first parameter. Instead constructor should only have the host part, and GrabResponse only the rest of the URL (without host).
– TheRoadrunner
Jul 15 '18 at 7:01
+1 Just used this to connect to my router, but it returns a Set-Cookie header, so you need to add the cookies to all subsequent requests if you happen upon same situation. p.s. to parse cookies you can use this answer: stackoverflow.com/a/1055883/289992
– bottlenecked
Jan 25 '14 at 10:07
+1 Just used this to connect to my router, but it returns a Set-Cookie header, so you need to add the cookies to all subsequent requests if you happen upon same situation. p.s. to parse cookies you can use this answer: stackoverflow.com/a/1055883/289992
– bottlenecked
Jan 25 '14 at 10:07
interesting. thanks for the suggestion
– kitwalker
Jan 25 '14 at 21:22
interesting. thanks for the suggestion
– kitwalker
Jan 25 '14 at 21:22
I know this is an ancient post, but if anyone like me stumbles over this problem and would like to use kitwalkers solution, be advised that the usage example above is incorrect. The DigestAuthFixer constructor and the GrabResponse method should not have the full URL as first parameter. Instead constructor should only have the host part, and GrabResponse only the rest of the URL (without host).
– TheRoadrunner
Jul 15 '18 at 7:01
I know this is an ancient post, but if anyone like me stumbles over this problem and would like to use kitwalkers solution, be advised that the usage example above is incorrect. The DigestAuthFixer constructor and the GrabResponse method should not have the full URL as first parameter. Instead constructor should only have the host part, and GrabResponse only the rest of the URL (without host).
– TheRoadrunner
Jul 15 '18 at 7:01
add a comment |
This article from 4GuysFromRolla appears to be what you are looking for:
http://www.4guysfromrolla.com/articles/102605-1.aspx
Unfortunately this does not talk about dealing with "nonce" or similar. It is implied that Digest, but how can it know the correct nonce of the previous request without using the "auto auth"?
– user166390
Sep 21 '11 at 5:02
add a comment |
This article from 4GuysFromRolla appears to be what you are looking for:
http://www.4guysfromrolla.com/articles/102605-1.aspx
Unfortunately this does not talk about dealing with "nonce" or similar. It is implied that Digest, but how can it know the correct nonce of the previous request without using the "auto auth"?
– user166390
Sep 21 '11 at 5:02
add a comment |
This article from 4GuysFromRolla appears to be what you are looking for:
http://www.4guysfromrolla.com/articles/102605-1.aspx
This article from 4GuysFromRolla appears to be what you are looking for:
http://www.4guysfromrolla.com/articles/102605-1.aspx
edited Sep 21 '11 at 22:58
answered May 7 '09 at 18:17
Sam AxeSam Axe
27.7k7 gold badges45 silver badges75 bronze badges
27.7k7 gold badges45 silver badges75 bronze badges
Unfortunately this does not talk about dealing with "nonce" or similar. It is implied that Digest, but how can it know the correct nonce of the previous request without using the "auto auth"?
– user166390
Sep 21 '11 at 5:02
add a comment |
Unfortunately this does not talk about dealing with "nonce" or similar. It is implied that Digest, but how can it know the correct nonce of the previous request without using the "auto auth"?
– user166390
Sep 21 '11 at 5:02
Unfortunately this does not talk about dealing with "nonce" or similar. It is implied that Digest, but how can it know the correct nonce of the previous request without using the "auto auth"?
– user166390
Sep 21 '11 at 5:02
Unfortunately this does not talk about dealing with "nonce" or similar. It is implied that Digest, but how can it know the correct nonce of the previous request without using the "auto auth"?
– user166390
Sep 21 '11 at 5:02
add a comment |
I'm currently observing the same issue, though the web server I'm testing this against is my own. The server logs show:
Digest: uri mismatch - </var/path/some.jpg> does not match request-uri
</var/path/some.jpg?parameter=123456789>
I tried removing the arguments from the URL (as that seemed to be what's different), but the error still occurred just like before.
My conclusion is that the URL arguments have to be included in the digest hash as well and that the HttpWebRequest
is for some reason removing it.
add a comment |
I'm currently observing the same issue, though the web server I'm testing this against is my own. The server logs show:
Digest: uri mismatch - </var/path/some.jpg> does not match request-uri
</var/path/some.jpg?parameter=123456789>
I tried removing the arguments from the URL (as that seemed to be what's different), but the error still occurred just like before.
My conclusion is that the URL arguments have to be included in the digest hash as well and that the HttpWebRequest
is for some reason removing it.
add a comment |
I'm currently observing the same issue, though the web server I'm testing this against is my own. The server logs show:
Digest: uri mismatch - </var/path/some.jpg> does not match request-uri
</var/path/some.jpg?parameter=123456789>
I tried removing the arguments from the URL (as that seemed to be what's different), but the error still occurred just like before.
My conclusion is that the URL arguments have to be included in the digest hash as well and that the HttpWebRequest
is for some reason removing it.
I'm currently observing the same issue, though the web server I'm testing this against is my own. The server logs show:
Digest: uri mismatch - </var/path/some.jpg> does not match request-uri
</var/path/some.jpg?parameter=123456789>
I tried removing the arguments from the URL (as that seemed to be what's different), but the error still occurred just like before.
My conclusion is that the URL arguments have to be included in the digest hash as well and that the HttpWebRequest
is for some reason removing it.
answered Jul 3 '10 at 18:26
CygonCygon
7,2787 gold badges35 silver badges47 bronze badges
7,2787 gold badges35 silver badges47 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f594323%2fimplement-digest-authentication-via-httpwebrequest-in-c-sharp%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown