C# connecting to web page with authentication - c#

So I've been trying to fetch a web page that uses authentication to a string and save it to a file. It should be pretty basic so I hope someone can see my errors. I'm very new to C# so treat me thereafter :)
This code functions to some extend, but the file I get is the html for the login screen and not the page that its shown for users that is logged in. What is it I'm doing wrong?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace fetchingweb
{
class WebAutheticator
{
static void Main(string[] args)
{
string htmlHer = GetWeb();
StreamWriter file = new
StreamWriter("C:\\Users\\user\\Documents\\atextfile.txt");
file.Write(htmlHer);
file.Close();
} //main end
private static string GetWeb()
{
WebClient wc = new WebClient();
wc.Credentials = new NetworkCredential("user", "pass");
string url = "http://someurl.com/index.php";
try
{
using (Stream stream = wc.OpenRead(new Uri(url)))
{
using (StreamReader reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
catch (WebException e)
{
return "failure!";
}
} //getweb end
} //class end
} //namespace end

You are using NetworkCredential to login at the webapp, but the webapp is using some kind of forms authentication.
As long as the webapp is not configured to use network credentials this will not work.
Since this is a php application I guess it uses plain forms auth and that you will need to post username/password to the login page before continuing.

Look at the code on the login page of the site you're trying to log into and download.
There will be a <FORM..> section, if its post you need to post, if its get you use get. It will either post to a new page, and possibly use redirection, or, even refer to itself. Chances are it will use either some form of session id, or cookies to prove you logged in.
Best way to understand this is to write a proxy, which takes your requests, and shows what you send and what you get back.. As this is the best way to understand what happens when you use things and what your program would need to do to mimic it

Related

How to implement Google Place API in C#.Net

I am developing a EPOS System in C#.NET. In My Project, i have to implement a scenario:
User will enter Zip Code/ Postal Code in a Text box.
Application using google places API will return City, Street and Town separately in 3 Tex box respectively.
Please any one help me how to implement this scenario in C#.net.
i already created Google Project on https://console.cloud.google.com/apis/credentials/key and generate Google Place API Key for my project.
I Have searched a lot on google but all example are implemented in asp.net, but i need in C# Net.
Anyone Help me.
Thanks in Advance.
I have implemented Some how but i don't know how to read it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Script.Serialization;
using Newtonsoft.Json;
namespace apidemo
{
class Program
{
String response, result;
const String apiKey= "My APi kEy";
static void Main(string[] args)
{
getdata("B11 4RA");
Console.ReadLine();
}
static async public void getdata(String code)
{
try
{
using (var client = new HttpClient())
{
var response = await client.GetStringAsync(String.Format("https://maps.googleapis.com/maps/api/place/autocomplete/json?key="+ apiKey + "&input=" +code));
Console.WriteLine(response);
}
}
catch (Exception ex) {
Console.Write(ex.ToString());
}
}
}
}
Output is this
If we look at the documentation for the Google Places API, we can see the format of the JSON that a request to the API returns. You can traverse the json object and get your required values as in below snippet.
JObject objectContainer = response.Value<JObject>("candidates");
foreach (KeyValuePair<string, JToken> tag in objectContainer)
{
if(tag.key=="formatted_address")
var address = tag.value;
if(tag.key=="name")
var name = tag.value;
}
With a simple HTTP request to the Google Places API, we can then use above code to get required fields.
using (var client = new HttpClient())
{
var response = await client.GetStringAsync("https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=YOUR_POSTCODE&inputtype=textquery&&fields=photos,formatted_address,name,opening_hours,rating&key=YOUR_API_KEY");
var result = JsonConvert.DeserializeObject<PlacesApiQueryResponse>(response);
}

How to access a SOAP service through an authenticated proxy server in C#?

Let me start by saying I am new to C# and SOAP services. I need to wring a program that will read data from a flat file and make a call to a SOAP web service to insert the data into that system.
My network is behind a proxy server that I have to authenticate with a username and password in order to access anything external to our network or on the internet. I can not figure out how to do this. I have been searching for answers and trying the results I have found, but I have had no luck. The error message I get is
"The request failed with an empty response"
I have set up the service in SOAPUI, and if I supply my proxy settings to the SOAPUI preferences, it is able to leave our network and get a response.
The username and password I have in the example below are not real, but the response doesn't change either way. It seems to me like it never attempts to access or authenticate through the proxy server.
Can anyone help me out? Thank you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
ConsoleApp6.ASC.Service1 soap = new ConsoleApp6.ASC.Service1();
ConsoleApp6.ASC.UserCredentialsSoapHeader credential = new ConsoleApp6.ASC.UserCredentialsSoapHeader();
credential.UserName = "soap_user_name";
credential.Password = "soap_password";
soap.UserCredentialsSoapHeaderValue = credential;
soap.Proxy = new WebProxy("http://gateway.zscalertwo.net:80/", true);
soap.Proxy.Credentials = new NetworkCredential("username", "password", "domain");
try
{
ASC.AppraiserLicense licenceInfo = soap.GetLicenseByLicenseNumber("46000049784", 1, "NY");
Console.WriteLine(licenceInfo);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadLine();
}
}
}
Console Output
System.Net.WebException: The request failed with an empty response.
at
System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClie
ntMessage message, WebResponse response, Stream responseStream,
Boolean asyncCal l) at
System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String
methodN ame, Object[] parameters) at
ConsoleApp6.ASC.Service1.GetLicenseByLicenseNumber(String
LicenseNumber, B yte LicType, String st_abbr) in
C:\Users\mkurick\Documents\Visual Studio 2017\Pr
ojects\ConsoleApp6\ConsoleApp6\Web References\ASC\Reference.cs:line
120 at ConsoleApp6.Program.Main(String[] args) in
C:\Users\mkurick\Documents\Visu al Studio
2017\Projects\ConsoleApp6\ConsoleApp6\Program.cs:line 26

Xero Public Application Integration With C#

I want to integrate xero with c# windows service application.
I did not find a simple code snippet to connect xero with c#. I don't want any user interaction while authorising the user with xero.
I found the code below but it redirects me to xero login page to authenticate and then generates the verification code, how can I avoid this and go ahead because in windows service I will not have any gui to enter verification code.
using System;
using System.Linq;
using System.Windows.Forms;
using Xero.Api.Core;
using Xero.Api.Example.Applications.Public;
using Xero.Api.Example.TokenStores;
using Xero.Api.Infrastructure.OAuth;
using Xero.Api.Serialization;
namespace XeroIntegrationTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ConnectXero();
}
public void ConnectXero()
{
try
{
// Public Application Sample
var user = new ApiUser { Name = Environment.MachineName };
string consumerKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string consumerSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var public_app_api = new XeroCoreApi("https://api.xero.com/api.xro/2.0/", new PublicAuthenticator("https://api.xero.com/api.xro/2.0/", "https://api.xero.com/oauth/RequestToken", "oob",
new MemoryTokenStore()),
new Consumer(consumerKey, consumerSecret), user,
new DefaultMapper(), new DefaultMapper());
var public_contacts = public_app_api.Contacts.Find().ToList();
} catch (Exception ex)
{
MessageBox.Show(ex.Message + ex.StackTrace);
}
}
}
}
But it generates
oauth_problem=permission_denied&oauth_problem_advice=The%20consumer%20was%20denied%20access%20to%20this%20resource
error.
Hope someone will help me.
You need to integrate with "privateKeyAuthendicator" method.
To do this :
1.Create Private/Public Key using below link
https://developer.xero.com/documentation/api-guides/create-publicprivate-key
2.Create ConsumerKey and ConsumerSecret
3.Include Key file into your project folder
4.Use below code snippet to access Xero
var private_app_api = new XeroCoreApi(_xeroSettings.Value.Url, new PrivateAuthenticator(privatekeyFilePath, privatekeypassword),
new Consumer(consumerKey,consumerSecret), null,
new DefaultMapper(), new DefaultMapper());
You need to integrate using the "PrivateAuthenticator" method. The method you are using is the public one and uses a different authentication process which is not suitable for a windows service.
To do this:
Visit the Xero developer portal
Go to the "My Apps" section
Select "Add Application"
Select "Private" from the radio button options (this is important)
Generate a Private/Public key combination (google how to do this)
Follow the code samples in the readme for setting up a connection using the PrivateAuthenticator method

How can I tell what referrer address my server side app is using

This seems like a simple question. I'm using a server-side app written in C# to do a simple api key connection to youtube from a Windows Server 2008 server. When I run it without an ip referer restriction it works fine. So I set up an ip referer restriction. I ran ipconfig on my server and used the main ip address listed, and I got an ipreferer blocked error. I also tried the other ip addresses listed. I've included a screenshot of my ipconfig with notes.
So I know the program is passing youtube some referer ip, and it's not the right one. How can I tell what the referer ip it is passing?
The code is below:
/*
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
namespace Google.Apis.YouTube.Samples
{
/// <summary>
/// YouTube Data API v3 sample: search by keyword.
/// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher.
/// See https://code.google.com/p/google-api-dotnet-client/wiki/GettingStarted
///
/// Set ApiKey to the API key value from the APIs & auth > Registered apps tab of
/// https://cloud.google.com/console
/// Please ensure that you have enabled the YouTube Data API for your project.
/// </summary>
internal class Search
{
List<string> HTMLText = new List<string>();
Boolean openDiv = true;
string mainVideoTarget = "main_video";
string menuDiv = "video_menu_images";
string thumbnailDiv = "thumb";
[STAThread]
static void Main(string[] args)
{
try
{
new Search().Run().Wait();
}
catch (AggregateException ex)
{
foreach (var e in ex.InnerExceptions)
{
Console.WriteLine("Error: " + e.Message);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private async Task Run()
{
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "API_KEY_HERE",
ApplicationName = this.GetType().ToString()
});
var channelsListRequest = youtubeService.Channels.List("contentDetails");
channelsListRequest.Id = "CHANNEL_ID_HERE";
// Retrieve the contentDetails part of the channel resource for the authenticated user's channel.
var channelsListResponse = await channelsListRequest.ExecuteAsync();
//a bunch of stuff down here to read the data from youtube
//write it into an html file which I left out because it's irrelevant
}
}
}
ipconfig is returning the internal IP address. Try a site like http://whatismyip.com and use the IP address that site returns as the Referer address.
Thanks for the help and suggestions, especially pointing out that the ip from ipconfig is not what the router is passing. I know about whatsmyip but I wasn't 100% sure if that's the same ip that a console app would be using. Turns out it was. I was able to find the ip passed by running this simple little script:
using System;
using System.IO;
using System.Net;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
HttpWebRequest htwr = (HttpWebRequest)WebRequest.Create("[any url that can get an http connection]");
WebResponse response = htwr.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
reader.Close();
response.Close();
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
}
One of the variables returned is REMOTE_ADDR which is what I was looking for.

How do I use the Redmine REST API over https from .NET?

Our internal Redmine server only allows me to connect via HTTPS. Here's how I tried to use the REST API via HTTPS from .NET:
As suggested in Using the REST API with .NET, setting the host variable to "https://redmine.company.com/redmine/" and the apiKey to "ffffffffffffffffffffffffffffffffffffffff".
From scratch with the following code:
using System.IO;
using System.Net;
class Program
{
static void Main(string[] args)
{
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => true;
var request = (HttpWebRequest)WebRequest.Create(
"https://redmine.company.com/redmine/issues/149.xml?key=ffffffffffffffffffffffffffffffffffffffff");
request.CookieContainer = new CookieContainer();
request.Method = "GET";
using (var response = request.GetResponse()) // Hangs here
using (var responseStream = response.GetResponseStream())
using (var memoryStream = new MemoryStream())
{
responseStream.CopyTo(memoryStream);
}
}
}
Of course, company.com and ffffffffffffffffffffffffffffffffffffffff are just placeholders for my real company and my real API key on my account page. Both attempts hang for some time before timing out with a WebException (see the Hangs here comment in attempt 2). I then tried to download other stuff from the Redmine server (like e.g. time_entries.csv, atom feeds, etc.), each time with exactly the same result.
So far so bad. However, if I copy-paste the URL https://redmine.company.com/redmine/issues/149.xml?key=ffffffffffffffffffffffffffffffffffffffff into my browser, I get exactly the response I would expect. So, it seems as though our Redmine server behaves as it should, but somehow I can't get it to work from .NET.
I have successfully downloaded stuff from other HTTPS sites and have managed to download issue data from http://demo.redmine.org with the code of attempt 2 (of course with adapted URLs, etc.). So, it seems there might be something special about how Redmine communicates over HTTPS.
If anybody is successfully using the Redmine REST API over HTTPS from .NET, I'd be really grateful for some pointers on what I'm doing wrong.
Also, suggestions on how to debug this from the client side would be greatly appreciated. So far I've tried Fiddler2, with no success. As soon as I enable its "Decrypt HTTPS traffic" setting then I no longer get an answer when I make the request in Internet Explorer.
We use redmine-net-api which supports HTTP/S connection and authentication based on API keys.
RedmineManager rm = new RedmineManager("https://&ltyour-address&gt", &ltapi-key&gt, "random-password");
IList&ltIssue&gt issues = rm.GetObjectList&ltIssue&gt(new NameValueCollection() { { "project_id", &ltproject-id&gt } });
Try this, it works for me:
// Allow every secure connection
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => true;
// Create redmine manager (where URL is "https://10.27.10.10/redmine" for me and redmineKey is my redmine API key
RedmineManager redmineManager = new RedmineManager(redmineURL, redmineKey);
// Create your query parameters
NameValueCollection queryParameters = new NameValueCollection { { "project_id", "4" }, {"tracker_id", "17"}, { "offset", "0" } };
// Perform your query
int issuesFound = 0;
foreach (var issue in redmineManager.GetObjectList<Issue>(queryParameters, out issuesFound))
{
// By default you get the 25 first issues of the project_id and tracker_id specified.
// Play with the offset to get the rest
queryParameters["offset"] = ....
}
Explicit passing SecurityProtocolType.Tls12 value for securityProtocolType parameter solved the problem for my case:
RedmineManager redmineManager = new RedmineManager(_host, _apiKey,
securityProtocolType: SecurityProtocolType.Tls12);

Categories

Resources