Forms Auth and HttpWebRequest credential -- How?

T

TK

I have a trouble to get web resopnse from an aspx page which is secured by
Forms Authentication with custom user account database.
My client application is a console application but not a browser. I want to
download a file from my webapplication.
I've learned that the NetworkCredential class gives a way to go but no luck.
My code is as following...just dump out the web response for debugging.

// C#
public void Download(string username, string password, string filename)
{
HttpWebRequest req =
(HttpWebRequest)WebRequest.Create("http://myserver/myapp/download.aspx?file=
" + filename);
req.Method = "GET";
req.Credentials = new NetworkCredential(username, password);
HttpWebResponse res = (HttpWebResponse)req.GetResponse();

StreamReader sr = new StreamReader(res.GetResponseStream());
char[] buf = new char[256];
int count;
while((count = sr.Read(buf, 0, 256)) > 0)
{
string s = new string(buf, 0, count);
Console.Write(s);
}
res.Close();
}

It seems the NetworkCredential doesn't work because above code dumps the
html document of the login page.
How can I accomplish this?
Please help!

best regards,
TK
 
B

bruce barker

Network Credentials are not used with forms authentication. Using forms
authentication with a console app will be fun.

a little background on forms authentication (FA). when a browser hits a FA
site for the first time, the site redirects the browser to the login page.
the url is decorated with the utl of the return page. the user fill in the
login info, and posts to the site. the login page verifies the login data
and if ok, stores a login ticket in the cookie which is sent back to the
browser along with a redirect to the original page.

to get this working in your app do.

1) do get of the requested page. if you are not logged in, the response will
be a redirect header (307 probably).
2) do a get of the response url which should be the login page
3) parse the login page html for the __VIEWSTATE hidden field. you will need
to post this value.
4) post the __VIEWSTATE, and login field values to the login page aspx.
5) if valid, you should get another redirect response with a cookie to use
on future get/puts, and the url of the original page you requested. if the
site is cookieless, you will get a munged url of the orginally requested
page.
6) with the login cookie or munged url, you can now get your original page.


-- bruce (sqlwork.com)
 
T

TK

Thank you for help, bruce.

I've followed the way you mentioned. Now my app works fine in the step 1 to
step 4, but doesn't work as expected in step 5. I also learned that I have a
SessionState/Cookies handling issue in these process. So I added some codes
for this purpose. Now my code looks like this...

static void Download(string username, string password, string filename)
{
CookieContainer Cookies = new CookieContainer();
TargetUrl = new Uri("http://myserver/myapp/download.aspx?file=" +
filename);

HttpWebRequest req =
(HttpWebRequest)WebRequest.Create(TargetUrl.AbsoluteUri);
req.Method = "GET";
req.AllowAutoRedirect = false;
req.CookieContainer = Cookies;

HttpWebResponse res = (HttpWebResponse)req.GetResponse();
String s;

if (res.StatusCode == HttpStatusCode.Found)
{
TargetUrl = new Uri(TargetUrl, res.Headers["Location"]);
req = (HttpWebRequest)WebRequest.Create(TargetUrl.AbsoluteUri);
req.Method = "GET";
req.AllowAutoRedirect = false;
req.CookieContainer = Cookies;

res = (HttpWebResponse)req.GetResponse();

String ViewState = null;
StreamReader sr2 = new StreamReader(res.GetResponseStream());
Regex reg = new
Regex("name=\"__VIEWSTATE\"\\s*value\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))
",RegexOptions.IgnoreCase|RegexOptions.Compiled);

while ((s = sr2.ReadLine()) != null)
{
Match m = reg.Match(s);
if (m.Success)
{
ViewState = m.Groups[1].ToString();
break;
}
}
res.Close();

s = "TextBox1=" + username + "&TextBox2=" + password + "&__VIEWSTATE=" +
ViewState;
req = (HttpWebRequest)WebRequest.Create(res.ResponseUri.Scheme + "://" +
res.ResponseUri.Host + res.ResponseUri.AbsolutePath);
req.Method = "POST";
req.ContentLength = s.Length;
req.ContentType = "application/x-www-form-urlencoded";
req.CookieContainer = Cookies;

StreamWriter sw = new StreamWriter(req.GetRequestStream());
sw.Write(s);
sw.Close();

res = (HttpWebResponse)req.GetResponse();
}

StreamReader sr = new StreamReader(res.GetResponseStream());
while((s = sr.ReadLine()) != null)
{
Console.Write(s);
}

res.Close();
}


The HttpWebResponse after POSTing the login page with id/pass/viewstate
doesn't have expected second redirection to the original page. Instead, it
shows another new login page with StatusCode.OK.

Could you give me another hint please?

best regards,
TK
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top