403 forbidden exception in accessing access token - google-calendar-api

I am trying to generate a new access token when access token from Google is expired. But On my production server i am getting below mentioned exception:
Exception:
at System.Net.HttpWebRequest.GetResponse() at System.Net.HttpWebRequest.GetResponse() at
GoogleCalendarProvider_V3.ExchangeCodeWithAccessAndRefreshToken(String RefreshToken)
Exception Message:
The remote server returned an error: (403) Forbidden.
I am creating a http web request in order to get the access token. please check the below code for this
string Url = "https://accounts.google.com/o/oauth2/token";
string grant_type = "refresh_token";
string data = "client_id={0}&client_secret={1}&refresh_token={2}&grant_type={3}";
HttpWebRequest request = HttpWebRequest.Create(Url) as HttpWebRequest;
string result = string.Empty;
request.Method = "POST";
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
string param = string.Format(data, ClientID, ClientSecret, RefreshToken, grant_type);
request.Credentials = CredentialCache.DefaultCredentials;
var bs = Encoding.UTF8.GetBytes(param);
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse response = request.GetResponse())
{
var sr = new StreamReader(response.GetResponseStream());
result = sr.ReadToEnd();
sr.Close();
}
please help me in this context.

Have a look at this question Youtube API C# OAuth token exchange for access_token returns invalid request
It looks to be a similar problem.

Related

linkedin underlying connection was closed

Our app uses oauth2 with linkedin to post to our customer's LI profile. The method to authorize a user works fine however the next section of code to get the access token results in an "Underlying connection was closed: An unexpected error occurred on a send" exception. The inner exception says "Authentication failed because the remote party has closed the transport stream".
I've verified our application credentials are correct and this had been working up until today as far as we can tell. The errors make it sound like an issue on LinkedIn's side, but I'm not 100% sure. Any ideas on how I can troubleshoot this?
Here's the code of the method that's failing.
var accessCodeUri =
string.Format(
"https://www.linkedin.com/uas/oauth2/accessToken?format=json&grant_type=authorization_code&code={0}&redirect_uri={1}&client_id={2}&client_secret={3}",
authorizationCode,
redirectUri.AbsoluteUri,
linkedInApiKey,
linkedInSecretKey);
string responseFromServer = string.Empty;
WebRequest request = WebRequest.Create(new Uri(accessCodeUri).AbsoluteUri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = 0;
request.Headers["UserAgent"] = "JB oAuth2";
Stream dataStream = request.GetRequestStream();
string postData = string.Empty;
byte[] postArray = Encoding.ASCII.GetBytes(postData);
dataStream.Write(postArray, 0, postArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
var reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
return responseFromServer;
Adding the following to the top of the method seems to have fixed the problem.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Calling Rest Api with HTTP authentication

I have to call a Rest API securely. I have an authenticate API which returns a token. I need to add this token the API I am calling.
This is the usual way I know of calling the Rest API. I need to append string token to this request.
// *** Establish the request
string token= getAuthenticate(username,password,out token );
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(lcUrl);
// *** Retrieve request info headers
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader loResponseStream = new StreamReader(response.GetResponseStream());
string lcHtml = loResponseStream.ReadToEnd();
response.Close();
loResponseStream.Close();
Not Sure what's the problem... To get the response from the Rest Uri you can do like below :
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(yourUrl + token); // Append Here
request.Method = "GET"; // GET or POST Define Here
//http.Accept = "application/json"; // Add if require
//http.ContentType = "application/json"; // Add if require
String test = String.Empty;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
test = reader.ReadToEnd();
reader.Close();
dataStream.Close();
}
Or You can use Simple requests through WebClient:
For Example:
WebClient webClient = new WebClient();
string json = string.Empty;
// Downloads JSon String
json = webClient.DownloadString("http://api.openweathermap.org/data/2.5/weather?q=London,uk"); // Replace your URL + Token...
There is third party component also available = RestSharp.
I am using HttpClient, no different at all. I thought this way more clean : http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client
var uri = "http://example.com";
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token_you_want_to_used);
var response = await httpClient.GetAsync(uri);
string result = await response.Content.ReadAsStringAsync();
}

Web service Error on retrieve a word document

I get an error when trying to retrieve word document by webservice
HttpWebRequest request;
Uri uri = new Uri(serverUrl +
"/bare.aspx/" + Request.PathInfo);
request = (HttpWebRequest)WebRequest.CreateDefault(uri);
request.KeepAlive = false;
request.AllowAutoRedirect = false;
request.ReadWriteTimeout = -1;
request.Timeout = -1;
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
request.Method = "POST";
request.ContentType = "application/octet-stream";
// Serialize argument into request stream
Hashtable arguments = new Hashtable();
arguments["templateFile"] = templateFile;
arguments["hSetDataSource"] = hSetDataSource;
arguments["hSetRepeatBlock"] = hSetRepeatBlock;
arguments["messageForEmptyWord"] = messageForEmptyWord;
arguments["hImageBefore"] = hImageBefore;
arguments["hImageAfter"] = hImageAfter;
arguments["hImageInsideRepeater"] = hImageInsideRepeater;
MemoryStream buf = new MemoryStream();
BinaryFormatter fmt = new BinaryFormatter();
fmt.Serialize(buf, arguments);
request.ContentLength = buf.Length;
Stream reqStream = request.GetRequestStream();
buf.WriteTo(reqStream);
reqStream.Close();
buf.Close();
// Retreive word document from response and return it
// TODO: refactor this to stream directly into the response
HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
When I check the webservice response (HttpWebResponse resp), I get the following error:
System.Net.WebException: The remote server returned an error: (404) Not Found.
I don't understand where is the problem, thank you in advance for your help.
You are not hitting the endpoint. A 404 means the server could not find the URL you are requesting. Verify your .asmx URL by putting it in your web browser. If that works then make sure you code is using that same URL.

How to send authorized request

I send programatically a request to remote server:
string xml = "SomeXML Data";
string url = #"http://someserver.com";
WebRequest request = WebRequest.Create(url);
request.Method = "Post";
request.ContentType = "text/xml";
//The encoding might have to be chaged based on requirement
UTF8Encoding encoder = new UTF8Encoding();
byte[] data = encoder.GetBytes(xml); //postbody is plain string of xml
request.ContentLength = data.Length;
Stream reqStream = request.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
System.Net.WebResponse response = request.GetResponse();
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
string str = reader.ReadToEnd();
but this code throws error:
The remote server returned an error: (401) Unauthorized.
I know user/pass to autorize when IE ask me.
Could anyone help me how to send authorized request?
Thanks!
webClient.Credentials = new NetworkCredential("Login", "Password");
Server seems to use Windows Authentication - although I am only guessing. If it is so, add this line:
request.Credentials = CredentialCache.DefaultCredentials;
looks like the server is using windows integrated security?
try something like this
WebRequest req = WebRequest.Create(tokenUri);
req.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
req.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

convert HTTP request code to HTTPS request code

I have got following code witch are sending xml file on HTTP protocol and getting response back as xml file from webserver and its working fine with HTTP protocol, but now i need to send such a XML file to HTTPS protocol (not http) and need to get response as xml file from it. the code to send xml file and get response from HTTP is :
string targetUri = "http://www.hostelspoint.com/xml/xml.php"; /*this will be like: "https://www.hostelspoint.com/xml/xml.php"*/
System.Xml.XmlDocument reqDoc = new System.Xml.XmlDocument();
reqDoc.Load(Server.MapPath("~\\getdetail.xml"));
string formParameterName = "OTA_request";
string xmlData = reqDoc.InnerXml;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(targetUri);
string sendString = formParameterName + "=" + HttpUtility.UrlEncode(xmlData);
//string sendString = HttpUtility.UrlEncode(xmlData);
byte[] byteStream;
byteStream = System.Text.Encoding.UTF8.GetBytes(sendString);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteStream.LongLength;
using (Stream writer = request.GetRequestStream())
{
writer.Write(byteStream, 0, (int)request.ContentLength);
writer.Flush();
}
HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
string respStr = "";
if (request.HaveResponse)
{
if (resp.StatusCode == HttpStatusCode.OK || resp.StatusCode == HttpStatusCode.Accepted)
{
StreamReader respReader = new StreamReader(resp.GetResponseStream());
respStr = respReader.ReadToEnd(); // get the xml result in the string object
XmlDocument doc = new XmlDocument();
doc.LoadXml(respStr);
Label1.Text = doc.InnerXml.ToString();
}
}
There shouldn't be much difference in your code, as HTTP or HTTPS differs only in transport level, not in application level.
What may become a problem here is, if the server certificate used in the targetUri is trusted on your server. In this case the HTTPS identity cannot be verified.

Resources