HTTP POST + Webrequest

W

WIWA

Hi,

I want to login to a password protected website and fetch the content of the
page behind. I have based my code on
http://weblogs.asp.net/jdennany/archive/2005/04/23/403971.aspx. When I use
tools like ieHTTPHeaders v1.6, and I perform a normal login (using the
normal website), I see that the viewstate is
__VIEWSTATE=dDwxMzU4OTE3NTA2Ozs%2BTK88jS63JXN181X3N8zKivua8co%3D&txt_username=xxx&txt_password=xxxxxx&btn_login=Login.
When I verify my program, this is exactly the same.

In the HTML code, this is the relevant part:
<form name="_ctl0" method="post" action="loginpage.aspx"
language="javascript" onsubmit="if (!ValidatorOnSubmit()) return false;"
id="_ctl0">
<input type="hidden" name="__VIEWSTATE"
value="dDwxMzU4OTE3NTA2Ozs+TK88jS63JXN181X3N8zKivua8co=" />
<input name="txt_username" type="text" id="txt_username" />
<input name="txt_password" type="password" id="txt_password" />
<input type="submit" name="btn_login" value="Login" onclick="if
(typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); "
language="javascript" id="btn_login" />

But the problem is that it does not give me the correct page, it always
refers me to the original login page, which clearly shows me sth is wrong.
So, I have used Ethereal to see the HTTP post and below is what I get when I
use the normal website procedure as well as when I use my program. With my
program it always says in the get (after the post) the following: "Invalid
character in a Base-64 string". Maybe this is the problem?

Another problem is the viewstates. They are slightly different, depending on
using ieHttpHeaders or Etheral.

Anyone can help me? (For those interested I inserted my code below)



Using the normal website login:

HTTP POST => Hypertext Transfer Protocol
POST /loginpage.aspx HTTP/1.1\r\n
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/x-shockwave-flash, application/vnd.ms-excel,
application/vnd.ms-powerpoint, application/msword, */*\r\n
Referer: http://www.cleverpc.be/loginpage.aspx\r\n
Accept-Language: nl-be\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Accept-Encoding: gzip, deflate\r\n
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET
CLR 1.1.4322)\r\n
Host: www.cleverpc.be\r\n
Content-Length: 118\r\n
Connection: Keep-Alive\r\n
Cache-Control: no-cache\r\n
Cookie: ASP.NET_SessionId=lhjccg45vfhx3eixl1d3ye55\r\n
\r\n
Line-based text data: application/x-www-form-urlencoded
__VIEWSTATE=dDwxMzU4OTE3NTA2Ozs%2BTK88jS63JXN181X3N8zKivua8co%3D&txt_username=wom&txt_password=wauters&btn_login=Login

HTTP GET => Hypertext Transfer Protocol
HTTP/1.1 302 Found\r\n
Date: Sun, 02 Oct 2005 20:24:32 GMT\r\n
Server: Microsoft-IIS/6.0\r\n
X-Powered-By: ASP.NET\r\n
X-AspNet-Version: 1.1.4322\r\n
Location: /adminpages/adminindex.aspx\r\n
Cache-Control: private\r\n
Content-Type: text/html; charset=iso-8859-1\r\n
Content-Length: 144\r\n
\r\n
Line-based text data: text/html
<html><head><title>Object moved</title></head><body>
<h2>Object moved to <a href='/adminpages/adminindex.aspx'>here</a>.</h2>
</body></html>


Using my program:

HTTP POST => Hypertext Transfer Protocol
POST /loginpage.aspx HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 117\r\n
Expect: 100-continue\r\n
Host: www.cleverpc.be\r\n
\r\n
HTTP GET => Hypertext Transfer Protocol
GET /adminpages/adminindex.aspx HTTP/1.1\r\n
Host: www.cleverpc.be\r\n
\r\n

Hypertext Transfer Protocol
HTTP/1.1 500 Internal Server Error\r\n
Date: Sun, 02 Oct 2005 20:27:40 GMT\r\n
Server: Microsoft-IIS/6.0\r\n
X-Powered-By: ASP.NET\r\n
X-AspNet-Version: 1.1.4322\r\n
Cache-Control: private\r\n
Content-Type: text/html; charset=iso-8859-1\r\n
Content-Length: 4476\r\n
\r\n
Line-based text data: text/html
<html>
<head>
<title>Invalid character in a Base-64 string.</title>
<style>
\tbody {font-family:"Verdana";font-weight:normal;font-size:
..7em;color:black;}
\tp
{font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
\tb
{font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
\tH1 {
font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
\tH2 {
font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
\tpre {font-family:"Lucida Console";font-size: .9em}
\t.marker {font-weight: bold; color: black;text-decoration:
none;}
\t.version {color: gray;}
\t.error {margin-bottom: 10px;}
\t.expandable { text-decoration:underline; font-weight:bold;
color:navy; cursor:hand; }
</style>
</head>

<body bgcolor="white">

<span><H1>Server Error in '/' Application.<hr width=100%
size=1 color=silver></H1>

<h2> <i>Invalid character in a Base-64 string.</i>
</h2></span>

<font face="Arial, Helvetica, Geneva, SunSans-Regular,
sans-serif ">

<b> Description: </b>An





Program code

Public Function ForceLogin() As Boolean
Try
Dim loginDlgUri, username, password, mainConsoleUri, baseUri As String
baseUri = "http://www.test.com/"
loginDlgUri = baseUri & "loginpage.aspx"
mainConsoleUri = baseUri & "adminpages/adminindex.aspx"
username = "xxx"
password = "xxxxxx"
Dim cookies As CookieContainer = New CookieContainer
' perform the first http request against the asp.net application login
dialog.
Dim request As HttpWebRequest = WebRequest.Create(loginDlgUri)
'get the response object, so that we may get the session cookie.
Dim response As HttpWebResponse
response = request.GetResponse()
' populate the cookie container.
request.CookieContainer = cookies
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri)

'read the incoming stream containing the login dialog page.
Dim reader As StreamReader = New StreamReader(response.GetResponseStream())
Dim loginDlgPage = reader.ReadToEnd()
reader.Close()
' extract the viewstate value from the login dialog page. We need to post
this back,
' along with the username and password
Dim viewState As String = GetViewState(loginDlgPage)
' build postback string
' This string will vary depending on the page. The best
' way to find out what your postback should look like is to
' monitor a normal login using a utility like TCPTrace.
Dim postback As String = String.Format("__VIEWSTATE={0}&txt_username={1} &
txt_password={2}&btn_login=Login", viewState, username, password)
' our second request is the POST of the username / password data.
Dim request2 As HttpWebRequest = WebRequest.Create(loginDlgUri)
request2.Method = "POST"
request2.ContentType = "application/x-www-form-urlencoded"
request2.CookieContainer = cookies
' write our postback data into the request stream
Dim writer As StreamWriter = New StreamWriter(request2.GetRequestStream())
writer.Write(postback)
writer.Close()
'request2.GetResponse().Close()
'our third request is for the actual webpage after the login.
Dim request3 As HttpWebRequest = WebRequest.Create(mainConsoleUri)
request3.CookieContainer = cookies
reader = New StreamReader(request3.GetResponse().GetResponseStream())
' and read the response
Dim page As String = reader.ReadToEnd()
MessageBox.Show(page)
reader.Close()
' our webpage data is in the 'page' string.
Catch WebExcp As WebException
MessageBox.Show(WebExcp.ToString)
End Try
End Function
' extract the viewstate data from a page.
Private Function GetViewState(ByVal s As String) As String
Dim viewStateNameDelimiter As String = "__VIEWSTATE"
Dim valueDelimiter As String
Dim viewStateNamePosition, viewStateValuePosition, viewStateStartPosition,
viewStateEndPosition As Integer
valueDelimiter = "value="
viewStateNamePosition = s.IndexOf(viewStateNameDelimiter)
viewStateValuePosition = s.IndexOf(valueDelimiter, viewStateNamePosition)
viewStateStartPosition = viewStateValuePosition + Len(valueDelimiter)
viewStateEndPosition = s.IndexOf("""", viewStateStartPosition + 1)
Return httpUtility.urlencodenicode(s.Substring(viewStateStartPosition,
viewStateEndPosition - viewStateStartPosition))
End Function
 

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

Top