Reusing a session created to another website - c#

We have an aspx page with some Page_Load code that calls a third party's TokenGenerator.aspx page to generate an SSO token
private string GetSSOToken()
{
using (WebClient client = new WebClient())
{
//serverUri is https://theirsite.com/Token.aspx, ssoRequestParam is a NameValueCollection
byte[] responsebytes = client.UploadValues(serverUri.AbsoluteUri, "POST", ssoRequestParam);
var ssoToken = Encoding.UTF8.GetString(responsebytes);
return ssoToken;
}
}
The returned ssoToken is added to a URL used as an iframe src. It ends up looking like this:
var frameUrl = "https://theirsite.com/SSO.aspx?ssotoken=returnedToken";
frame.Attributes["src"] = frameUrl;
The page then loads in the browser and all is well. This has been working fine for awhile.
Now we need to add a way to logout of the SSO.aspx. In our Logout() method when logging out of our application, I try calling their logout page:
using (WebClient client = new WebClient())
{
var logoutUrl = "https://theirsite.com/SSO.aspx?logout=true";
var s = client.DownloadString(logoutUrl);
}
But the logout never happens; their application doesn't show the logout happening, and I can paste the frameUrl into a browser and see the page still.
As a test, this works to logout:
Generate the frameUrl.
Copy/paste the frameUrl into a browser: it loads fine.
In a new separate window, paste the logoutUrl: logout does not happen, can still load frameUrl.
In another tab of the same browser, paste the logoutUrl: logout happens, frameUrl gives appropriate "token expired" message.
So I am guessing this is because the first WebClient session is not the same as the second WebClient session... but I am not sure how to reuse the first session during logout.

Related

Call classic ASP function from ASPX

I am working on an old web application where pages were written in classic ASP and are wrapped in aspx pages using Iframes. I am rewriting one of those pages in ASP.NET (using C#) removing the dependency on Iframes altogether. The page_to_rewrite.asp call many other functions present in other ASP pages in the same application.
I am facing difficulty calling those ASP functions from aspx.cs. I tried to use WebClient class like this:
using (WebClient wc = new WebClient())
{
Stream _stream= wc.OpenRead("http://localhost/Employee/finance_util.asp?function=GetSalary?EmpId=12345");
StreamReader sr= new StreamReader(_stream);
string s = sr.ReadToEnd();
_stream.Close();
sr.Close();
}
Every request coming to this application is checked for a valid session cookie using an IIS HTTP module and if its not present user is redirected to login page. Now when I call this ASP page url from aspx I get the login page of my application as the response as no session cookie is present.
Can anyone please kindly suggest how can I call the ASP methods successfully.
As told by #Schadensbegrenzer in the comment I just had to pass the cookie in the request header like this:
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.Cookie] = "SessionID=" + Request.Cookies["SessionID"].Value;
Stream _stream= wc.OpenRead("http://localhost/Employee/finance_util.asp?function=GetSalary&EmpId=12345");
StreamReader sr= new StreamReader(_stream);
string s = sr.ReadToEnd();
_stream.Close();
sr.Close();
}
In other similar questions on StackOverflow some people have suggested to also include User-Agent in the request header if you are getting blank output from the asp page as some web servers require this value in the request headers. See if it helps in your case. Mine worked even without it.
Also you will have to handle the request in your ASP page something like this:
Dim param_1
Dim param_2
Dim output
param_1 = Request.QueryString("function")
param_2 = Request.QueryString("EmpId")
If param_1 = "GetSalary" Then
output = GetSalary(param_2)
response.write output
End If
Hope it helps!

How can I load a webpage into an iframe, using ASP.NET MVC?

I have an external webpage that I need to access using a HTTP Post, and include in an iframe. The webpage has an example set of instructions to access the page, listed below, but they assume a Windows Form solution; I am using ASP.NET MVC, instead.
How can I convert this WebBrowser centric solution into something that can successfully post to the external site, and load the results into an iframe?
private WebBrowser wb_inline = null;
private void Submit_Click(object sender, EventArgs e)
{
string url = "http://www.example.com";
string setupParameters = "account_token=abc123";
ServicePointManager.ServerCertificateValidationCallback =
(s, cert, chain, ssl) => true;
ASCIIEncoding encoding = new ASCIIEncoding();
var postData = setupParameters;
if (null == wb_inline)
{
wb_inline = new WebBrowser(this);
wb_inline.Location = new System.Drawing.Point(100, 277);
wb_inline.Size = new System.Drawing.Size(675, 650);
}
Controls.Add(wb_inline);
wb_inline.Visible = true;
string AdditionalHeaders = "Content-Type: application/json";
byte[] data = encoding.GetBytes(postData);
wb_inline.Navigate(payProsUrl, "", data, AdditionalHeaders);
}
Is there a way to do something like this, with a HttpWebResponse (or some other control), and include this in an iframe? I've been trying to adapt this, but without success yet.
According to w3schools:
An inline frame is used to embed another document within the current HTML document.
That said, iframe is used to load page contents via a given url and present it to user for interaction. After that you have little control over what user does with the loaded page (he can click links, post forms, etc). You cannot send HTTP request to an iframe as it's just a "window" to show another page and doesn't support complicated scenarios.
One more thing to consider is that the web page you're loading can be protected from embedding into an iframe.
In fact there are some options how you can achieve what you want. For a pure server-side solution using iframe you should do the following:
1.Create an action method, that will do the HTTP POST request to the url you need and fetch the result for presentation:
public ActionResult PostAndShow()
{
//do the posting
string result = requestStream.ReadToEnd(); //you can have similar code to fetch the server response
return Content(result);
}
2.In you webpage you will create an iframe that will point to your action PostAndShow and will show the result of your HTTP POST request to third-party server.
<iframe src="#Url.Action("PostAndShow", "My")" width="400" height="300"></iframe>

WebClient redirect to response page after POST of form

I'm having some trouble trying to POST some form values to a page + redirect the user. For example:
User clicks register button
Some form values are populated
WebClient POSTS these values and redirects to the external URL
I can achieve this without WebClient easily with an intermediate .aspx and a standard form with onload="document.forms[0].submit()" added to the body.
However, I would like to do this without an intermediate page. Is this possible using WebClient (or similar)?
I post my values like so: -
using (WebClient wc = new WebClient())
{
NameValueCollection nvc = new NameValueCollection(8);
nvc.Add("_charset_", "utf-8");
nvc.Add("shop_id", "");
nvc.Add("email", "");
nvc.Add("amount", "");
nvc.Add("curr", "");
nvc.Add("paymentType", "");
nvc.Add("kdnr", "");
nvc.Add("ordernr", "");
byte[] response = wc.UploadValues("https://www.trustedshops.com/shop/protection.php", nvc);
}
I can get the response from the byte array which is just the html of the page i post to, however, i want to actually send the user to the posted page so that they see the form prepoplated. Can this be done?
Thanks

changing webclient response time

I want to use facebook like button in my website. as most of my visitors are from Iran and facebook is filtered in Iran, if somebody comes from Iran, the like button gets filtered and the page gets very ugly. what I have thought to prevent this is to use webclient to try to connect to facebook. if successful, I place the like button, otherwise I don't:
string fb_result="failed";
WebClient webclient= new WebClient();
try{
fb_result=webclient.DownloadString("http://www.fabebook.com");
}
catch{
fb_result="failed"; //if its being filtered exception is raised
}
the in my html:
<%if(fb_result)!="failed"){%>
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
<div class="fb-like" data-href="http://www.mysite.com" data-send="true" data-width="450" data-show-faces="true"></div>
<%}%>
this works fine but the problem is, when webclient is unable to connect, it takes to much time to raise the error. is there any way to make webclient try for a shorter time and if not able to connect raise the error faster.
by the way, any other ways to check if connection to facebook is possible or not is appeciated. as this might not be the only way to check it.
As I stated in my comments, the WebClient code you've written will not work because it is executed on the server, so it will attempt to connect to Facebook using your webserver's connection, which will always succeed (unless your webhost goes offline).
The best approach is to have an AJAX request made by your page when it loads in the browser. It should make a request for a known resource on Facebook (such as their homepage, or the "Like" image itself). Your AJAX response handler will then load the rest of the Facebook client scripts if, and only if, the response is as-expected. If you test it by requesting the Like image then you just need to check the response's content-type (i.e. ensure it's image/png); if the response has a non-200 status code or if the request times-out then you don't load the Facebook scripts.

C# Downloading HTML from a website after logging in

I've recently been looking on how to get data from a website using C#. I tried using the WebBrowser object to navigate and log in, and that worked fine, but I keep getting the same problem over and over again: when I navigate to the wanted page I get disconnected.
I've tried several things like making sure that only one HtmlDocument exists but I still get logged out.
TLDR: how do you stay logged in, from page to page, while navigating a website with WebBrowser? Or are there better alternatives?
EDIT: So far I have the following code;
currentWebBrowser = new WebBrowser();
currentWebBrowser.DocumentText = #"<head></head><body></body>";
currentWebBrowser.Url = new Uri("about:blank");
currentWebBrowser.Navigate("http://google.com");
HttpWebRequest Req = (HttpWebRequest) WebRequest.Create("http://google.com");
Req.Proxy = null;
Req.UseDefaultCredentials = true;
HttpWebResponse Res = (HttpWebResponse)Req.GetResponse();
currentWebBrowser.Document.Cookie = Res.Cookies.ToString();
At which moment should I get the cookies? And is my code correct?
You have to preserve the cookies returned from your login request and reuse those cookies on all subsequent requests - the authentication cookie tells the server that you are in fact logged in already. E.g. see here on how to do that.

Categories