locked
HttpWebRequest and Forms Authentication RRS feed

  • Question

  • User-1014994263 posted
    I'm sure someone here has run into this problem before: I have a page where I create/execute a HttpWebRequest for another page on the same server, using POST to send serialized data to the requested page in the RequestStream. The problem is that I keep on getting back my login page, not the page I requested. Now I've tries a few different methods of sending the proper authentication credentials, but nothing seems to be working. This is what I've tried: HttpWebRequest req = ( HttpWebRequest )WebRequest.Create( myURL ); req.Method = "POST"; req.AllowWriteStreamBuffering = true; // this doesn't work req.Credentials = new NetworkCredential( userName, passwd ); // neither does this... string passstring = "userName:passwd"; string auth = "Forms " + Convert.ToBase64String( System.Text.Encoding.ASCII.GetBytes( passstring )); req.Headers.Add( "Authorization", auth ); // neither does this... req.Credentials = CredentialCache.DefaultCredentials; CredentialCache myCache = new CredentialCache(); myCache.Add( new Uri( myURL ), "Forms", new NetworkCredential( userName, passwd )); req.Credentials = myCache; Any ideas? This is what I have in my Web.config file: <authentication mode="Forms"> <forms loginUrl="login.aspx" name="IMSCookieAuth" protection="All" timeout="60"> </forms> </authentication> <authorization> <deny users="?" /> </authorization>
    Tuesday, June 1, 2004 1:19 PM

All replies

  • User-1014994263 posted
    Found an answer.... http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=340746
    Tuesday, June 1, 2004 2:44 PM
  • User-1014994263 posted
    Ok, maybe the code from the following link DOESN'T work... http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=340746 If I set a breakpoint in the requested page, I can see its Init and Load methods being called, but I still get the Login page in the response. Any ideas?
    Tuesday, June 1, 2004 3:33 PM
  • User390817712 posted
    Most forms authentication schemes use cookies. You'll first need to POST to the login page, which should send back a cookie in the response. You can pull the cookie out of the response by looking in the HttpWebResponse.Cookies property, then add the cookie to future requests using HttpWebRequest.CookieContainer.
    Tuesday, June 1, 2004 4:18 PM
  • User-1014994263 posted
    But If I'm doing this from a section of the web app, where I'm already logged in, why can't I use the Authentication Cookie set at login time? That's what I'm trying to do, as suggested in the link I posted. Doesn't seem to work for me. Anyone have any leads I coud look into, as to why it isn't working? Thanks.
    Tuesday, June 1, 2004 5:03 PM
  • User-1014994263 posted
    By not working, I mean that I keep on getting redirected to the login page. Anyone?
    Wednesday, June 2, 2004 10:48 AM
  • User-1014994263 posted
    Here's the code I'm trying to run. The file that always gets written is the login page. I can see in the server logs the request for GenTemplate.aspx, with a redirect code to the Login page. Anyone? Please? I'll mail you a shiny new quarter if you help me out with this problem. Honest. HttpWebRequest req = ( HttpWebRequest )WebRequest.Create( "http://localhost/IMS/GenTemplate.aspx" ); req.Method = "POST"; req.AllowWriteStreamBuffering = true; // This is required so that we don't get redirected to the Login page... // HttpCookie authCookie = Request.Cookies[ FormsAuthentication.FormsCookieName ]; Cookie newC = new Cookie( authCookie.Name, authCookie.Value, authCookie.Path, "localhost" ); req.CookieContainer = new CookieContainer(); req.CookieContainer.Add( newC ); // send my data to the GenTemplate.aspx page. Stream reqStream = req.GetRequestStream(); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize( reqStream, templateItem ); reqStream.Close(); // get the page returned and write it to a file. HttpWebResponse resp = ( HttpWebResponse )req.GetResponse(); Stream respStream = resp.GetResponseStream(); StreamReader rdr = new StreamReader( respStream ); string filePath = Server.MapPath( "templFiles\\" + templateItem.ItemID.ToString()); StreamWriter wrtr = new StreamWriter( filePath + "\\template.html" ); string inLine = rdr.ReadLine(); while( inLine != null ) { wrtr.WriteLine( inLine ); inLine = rdr.ReadLine(); } rdr.Close(); wrtr.Close();
    Wednesday, June 2, 2004 11:34 AM
  • User-319210309 posted
    I have a similar problem to this... Basically I have a search engine script that runs once a night and crawls my website, but right now it can only crawl the non-protected pages. Any pages that are protected by Forms Authentication in my web.config get redirected to the login page and the script crawls/indexes that instead of the real page. Anyone have any more info on this? thanks vc
    Wednesday, June 2, 2004 12:38 PM
  • User-319210309 posted
    Unguwunga did you ever get an answer to this? Thanks vc
    Wednesday, June 16, 2004 3:53 PM
  • User86621589 posted
    When you perform a HttpWebRequest you are essentially performing a new "web request" which is equivalent to a new session. Unless you pass the forms auth cookie that you have from your orginal session to you webrequest you would be redirected to the login page. If you have a requirement where you need to access your site via a HttpWebRequest class , I would recommend you to have some custom authentication mechanism that would set your auth token and use the auth token with each request. Thanks Raman
    Thursday, June 17, 2004 9:31 PM
  • User-319210309 posted
    ramaniyer can you see what's wrong with this code I started on this thread: http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=606929 thanks vc
    Thursday, June 17, 2004 10:01 PM
  • User86621589 posted
    What you need to understand is that a forms authentication ticket (a non- persistent one; which by the way is what you should be using) is dependant on a Session. When you perform a new WebRequest you are essentially initiating a new "session" with your server. So the original authticket that you had is pretty much invalid at this point (atleast to the server). So as I said before. you need to create a custom authentication scheme what will allow you to maintain your auth credentials across sessions. Hope this helps. Thanks Raman
    Wednesday, June 23, 2004 6:06 PM
  • User-319210309 posted
    Ok I see what you are saying but can you give me a little more direction on making this custom authentication scheme. Would I use something similar to this process whic uses security principal/identity and global.asx: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadvnet/html/vbnet10282003.asp If so how could you give me soe more detail as to how to modify this code to make the server think that there is a valid authticket on every web request. Thanks for your help! vc
    Wednesday, June 23, 2004 8:00 PM
  • User86621589 posted
    Hmm.. the custom scheme would be a big topic to discuss. Your authentication scheme will have to be valid across sessions, which means you would need a central authentication source. Let me forward you an article by paul sheriff that shows an implementation of a single sign on. This might be a bit of an overkill for your requirement. However, it will give you ideas. http://msdn.microsoft.com/asp.net/using/understanding/security/default.aspx?pull=/library/en-us/dnaspp/html/singlesignon.asp Thanks Raman
    Thursday, June 24, 2004 7:51 PM
  • User1291168073 posted

    Hi Allen,

    I am trying the same technique but its not taking me to the logged in area and always shows the login control on the page. 

    The website that I am trying to monitor for its login availability is in Asp.net 2.0 with server side controls and forms authentication. The server side controls html generated has long name and I am using the same to provide values in the post data. Below is my code snippet.

    private void SchedularCallback(object e)
    {
    // first, request the login form to get the viewstate value
    HttpWebRequest webRequest = WebRequest.Create(ConfigurationManager.AppSettings["LoginWebsiteURL"]) as HttpWebRequest;
    StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
    string responseData = responseReader.ReadToEnd();
    responseReader.Close();

    // extract the viewstate value and build out POST data
    string viewState = ExtractViewState(responseData);
    string postData = String.Format(
    "__VIEWSTATE={0}&ctl00$ctl00$ctl00$ContentPlaceHolderDefault$RACGPContent$ctl03$RACGP_LoginBody_15$RACGP_LoginBodyView$RACGP_LoginBody$UserName={1}&ctl00$ctl00$ctl00$ContentPlaceHolderDefault$RACGPContent$ctl03$RACGP_LoginBody_15$RACGP_LoginBodyView$RACGP_LoginBody$Password={2}&ctl00$ctl00$ctl00$ContentPlaceHolderDefault$RACGPContent$ctl03$RACGP_LoginBody_15$RACGP_LoginBodyView$RACGP_LoginBody$RACGP_LoginBodyButton:Log me in&__VIEWSTATEGENERATOR:CA0B0334", 
    viewState, ConfigurationManager.AppSettings["LoginWebsiteUsername"], ConfigurationManager.AppSettings["LoginWebsitePwd"]
    );

    // have a cookie container ready to receive the forms auth cookie
    CookieContainer cookies = new CookieContainer();

    // now post to the login form
    webRequest = WebRequest.Create(ConfigurationManager.AppSettings["LoginWebsiteURL"]) as HttpWebRequest;
    webRequest.KeepAlive = true;
    webRequest.AllowAutoRedirect = false;
    webRequest.Method = "POST";
    webRequest.ContentType = "application/x-www-form-urlencoded";
    byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(postData);
    webRequest.ContentLength = dataBytes.Length;
    webRequest.CookieContainer = cookies;

    // write the form values into the request message
    StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream());
    requestWriter.Write(postData);
    requestWriter.Close();

    responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());

    // and read the response
    responseData = responseReader.ReadToEnd();  //Receiving the same Login page in this response. Based on this response I need to perform something
    responseReader.Close();

    }

    private string ExtractViewState(string s)
    {
    string viewStateNameDelimiter = "__VIEWSTATE";
    string valueDelimiter = "value=\"";

    int viewStateNamePosition = s.IndexOf(viewStateNameDelimiter);
    int viewStateValuePosition = s.IndexOf(valueDelimiter, viewStateNamePosition);

    int viewStateStartPosition = viewStateValuePosition + valueDelimiter.Length;
    int viewStateEndPosition = s.IndexOf("\"", viewStateStartPosition);

    return HttpUtility.UrlEncodeUnicode(
          s.Substring(
          viewStateStartPosition,
          viewStateEndPosition - viewStateStartPosition)
          );
    }

    Please advice me what to do.

    Tuesday, December 15, 2015 1:31 AM