I'm coding a C#.Net WPF 4.0 application that connects to Facebook and Twitter via oauth. With Facebook Graph API, I'm able to authorize, sign-in with oauth, exchange a temporary access_token to a almost persistent access token, and then, fetch any data only by adding the access_token next to my query, or posting on the wall, like this: [http://Url/query/access_token], and all of this without any SDK or any other library.
I tried to do the same with Twitter but I'm all mixed-up. I've been searching for examples on how to fetch some Json data the same way I do in Facebook, but I found nothing, probably because I don't know what to search. What is the flow that I need to follow to be able to make queries with only a direct url and a token?
you should do the following:
Get access token for the user: https://dev.twitter.com/docs/auth/obtaining-access-tokens
Use one of the REST APIs: https://dev.twitter.com/docs/api
Generate OAuth header and insert it into your request. Below is code from my app which uploads tweet and images into twitter - but GET requests will be similar. NOTE: I'm using 3rd-party OAuth class from https://cropperplugins.svn.codeplex.com/svn/Cropper.Plugins/TwitPic/OAuth.cs
var oauth = new OAuth.Manager();
oauth["consumer_key"] = Settings.TWITTER_CONSUMER_KEY;
oauth["consumer_secret"] = Settings.TWITTER_CONSUMER_SECRET;
oauth["token"] = item.AccessToken;
oauth["token_secret"] = item.AccessSecret;
var url = "https://upload.twitter.com/1/statuses/update_with_media.xml";
var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
foreach (var imageName in item.Images.Split('|'))
{
var fileData = PhotoThubmnailBO.GetThumbnailForImage(imageName, ThumbnailType.FullSize).Photo;
// this code comes from http://cheesoexamples.codeplex.com/wikipage?title=TweetIt&referringTitle=Home
// also see http://stackoverflow.com/questions/7442743/how-does-one-upload-a-photo-to-twitter-with-the-api-function-post-statuses-updat
var request = (HttpWebRequest) WebRequest.Create(url);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);
string boundary = "~~~~~~" +
Guid.NewGuid().ToString().Substring(18).Replace("-", "") +
"~~~~~~";
var separator = "--" + boundary;
var footer = "\r\n" + separator + "--\r\n";
string shortFileName = imageName;
string fileContentType = GetMimeType(shortFileName);
string fileHeader = string.Format("Content-Disposition: file; " +
"name=\"media\"; filename=\"{0}\"",
shortFileName);
var encoding = Encoding.GetEncoding("iso-8859-1");
var contents = new StringBuilder();
contents.AppendLine(separator);
contents.AppendLine("Content-Disposition: form-data; name=\"status\"");
contents.AppendLine();
contents.AppendLine(item.UserMessage);
contents.AppendLine(separator);
contents.AppendLine(fileHeader);
contents.AppendLine(string.Format("Content-Type: {0}", fileContentType));
contents.AppendLine();
// actually send the request
request.ServicePoint.Expect100Continue = false;
request.ContentType = "multipart/form-data; boundary=" + boundary;
using (var s = request.GetRequestStream())
{
byte[] bytes = encoding.GetBytes(contents.ToString());
s.Write(bytes, 0, bytes.Length);
bytes = fileData;
s.Write(bytes, 0, bytes.Length);
bytes = encoding.GetBytes(footer);
s.Write(bytes, 0, bytes.Length);
}
using (var response = (HttpWebResponse) request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception(response.StatusDescription);
}
}
}
Related
So I am trying to fetch my classes from my google classroom into my application:
Here is my google url:
var Googleurl = "https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=" + googleplus_redirect_url + "&prompt=consent&response_type=code&client_id=" + googleplus_client_id + "&scope=https://www.googleapis.com/auth/userinfo.profile+https://www.google.com/m8/feeds/+https://www.googleapis.com/auth/drive+https://www.googleapis.com/auth/drive.appdata+https://www.googleapis.com/auth/drive.file+https://www.googleapis.com/auth/drive.metadata+https://www.googleapis.com/auth/classroom.courses+https://www.googleapis.com/auth/classroom.profile.emails+https://www.googleapis.com/auth/classroom.profile.photos+https://www.googleapis.com/auth/classroom.rosters+https://www.googleapis.com/auth/classroom.rosters.readonly&access_type=offline";
After this I request for the access codes through:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
webRequest.Method = "POST";
Parameters = "code=" + code + "&client_id=" + googleplus_client_id + "&client_secret=" + googleplus_client_sceret + "&redirect_uri=" + googleplus_redirect_url + "&grant_type=authorization_code";
byte[] byteArray = Encoding.UTF8.GetBytes(Parameters);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = byteArray.Length;
Stream postStream = webRequest.GetRequestStream();
// Add the post data to the web request
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
WebResponse response = webRequest.GetResponse();
postStream = response.GetResponseStream();
StreamReader reader = new StreamReader(postStream);
string responseFromServer = reader.ReadToEnd();
GooglePlusAccessToken serStatus = JsonConvert.DeserializeObject<GooglePlusAccessToken>(responseFromServer);
I am able to get the access code as well as the refresh token all fine.
Now when I wish to fetch my classroom by:
string p="https://classroom.googleapis.com/v1/courses";
string auth = "Bearer "+access_token;
private bool GetClasses(string p,string auth)
{
using (var client = new WebClient())
{
var uri = new Uri(p);
//client.DefaultRequestHeaders.Authorization=new AuthenticationHeaderValue("Bearer", auth);
string req="Authorization: "+ auth;
client.Headers.Add(req);
var response = client.DownloadString(uri);
}
return true;
}
This code return an error of type:System.Net.WebException: {"The remote server returned an error: (403) Forbidden."}
I have used the same access_token to get all other scopes as shown in the scopes parameter in mu Googleurl. However I am unable to access my classes even though I've added the respective scopes for it.
Apparently to use google classroom related functionalities we need to enable the google classroom Api. As silly as it may sound I was ignorant about it(As I had already enabled the google Api service). Just had to activate the classroom api and the code worked like a charm.
This is less a question than an answer. I figured I would want to share this with you, since I was a bit confused finding so litte about the ebay OAuth 2.0 in combination with a C# web application.
I tried starting to use the RESTsharp library, but got stuck at the point, where the body content was created. RESTsharp prefers XML or JSON, ebay want's a string with params.
So to give you all a little help if you run into the same issue, I decided to post my solution (not using RESTsharp).
public class HomeController : Controller {
string clientId = "YOUR_CLIENT_ID";
string clientSecret = "YOUR_CLIENT_SECRET";
string ruName = "YOUR_RU_NAME";
// Redirect the request to get a request token
public ActionResult Index() {
var authorizationUrl =
"https://signin.sandbox.ebay.de/authorize?" +
"client_id=" + clientId + "&" +
"redirect_uri=" + ruName + "&" +
"response_type=code";
Response.Redirect(authorizationUrl);
return View();
}
// I used Test as a method to test the result in the controller, use your apropriate method here
public ActionResult Test(string code)
{
ViewBag.Code = code;
// Base 64 encode client Id and client secret
var clientString = clientId + ":" + clientSecret;
byte[] clientEncode = Encoding.UTF8.GetBytes(clientString);
var credentials = "Basic " + System.Convert.ToBase64String(clientEncode);
HttpWebRequest request = WebRequest.Create("https://api.sandbox.ebay.com/identity/v1/oauth2/token")
as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add(HttpRequestHeader.Authorization, credentials);
var codeEncoded = HttpUtility.UrlEncode(code);
var body = "grant_type=authorization_code&code=" + codeEncoded + "&redirect_uri=" + ruName;
// Encode the parameters as form data
byte[] formData = UTF8Encoding.UTF8.GetBytes(body);
request.ContentLength = formData.Length;
// Send the request
using (Stream post = request.GetRequestStream())
{
post.Write(formData, 0, formData.Length);
}
// Pick up the response
string result = null;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
result = reader.ReadToEnd();
}
ViewBag.Response = result;
return View();
}
If you output ViewBag.Response you will see the authorization code. Have fun.
How is your redirect url looking in sandbox? Seems like the url should be https. In this stage in dev environment and don't have server with https. How did you deal with that?
Ta
I need to secure wcf services based on OAuth. In this case Java application is passing me a token which i need to validate based on Oauth in .Net layer and if token is passed then need to call wcf services.
I have checked several examples based on OAuth but not got any idea to achieve this . Please help me how to achieve this based on OAuth in .net.
Finally i solved this by below implementation
var authHeader = WebOperationContext.Current.IncomingRequest.Headers.GetValues("Authorization");
if (authHeader == null || authHeader.Length == 0)
{
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
var parts = authHeader[0].Split(' ');
if (parts[0] == "Bearer")
{
string token = parts[1];
outgoingQueryString.Add("token", token);
byte[] postdata = Encoding.ASCII.GetBytes(outgoingQueryString.ToString());
var result = string.Empty;
var httpWebRequest = (HttpWebRequest)WebRequest.Create(oauthConfiguration.Setting.CheckUrl);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization", GetAuthorizationHeader(oauthConfiguration.Setting.ClientId, oauthConfiguration.Setting.ClientSecret));
httpWebRequest.ContentLength = postdata.Length;
using (Stream postStream = httpWebRequest.GetRequestStream())
{
postStream.Write(postdata, 0, postdata.Length);
postStream.Flush();
postStream.Close();
}
var response = (HttpWebResponse)httpWebRequest.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
I need to implement a service for sending invitation mail to users.
I am following Samlman's artice.
I am trying to get a permanent token for Yammer API using the post method shown below.
I'm currently getting:
Error: 404 "server not found error".
There is no inner exception.
Do I need to pass authHeader?
If yes, then how do I send the authHeader?
string authUrl1 = string.Format("https://www.yammer.com/session?client_id={0}" , CLIENT_ID);
string postBody = string.Format(
"{0}{1}{2}{3}{4}{5}{6}",
"utf8=%E2%9C%93&authenticity_token=",
System.Web.HttpUtility.UrlEncode(authToken),
"&network_permalink=&login=",
HttpUtility.UrlEncode(userName),
"&password=",
pwd,
"&remember_me=off");
//make the first post for code
postResults = MakePostRequest(postBody, authUrl1);
private static string MakePostRequest(string postBody, string url, string authHeader = null, string contentType = null)
{
string results = string.Empty;
try
{
//get the session and yamtrack cookie
SetCookies();
wr = WebRequest.CreateHttp(url);
wr.Method = "POST";
wr.CookieContainer = cc;
//if an authHeader was provided, add it as a Bearer token to the request
if (!string.IsNullOrEmpty(authHeader))
wr.Headers.Add("Authorization", "Bearer " + authHeader);
byte[] postByte = Encoding.UTF8.GetBytes(postBody);
if (string.IsNullOrEmpty(contentType))
wr.ContentType = "application/x-www-form-urlencoded";
else
wr.ContentType = contentType;
wr.ContentLength = postByte.Length;
Stream postStream = wr.GetRequestStream();
postStream.Write(postByte, 0, postByte.Length);
postStream.Close();
wResp = (HttpWebResponse)wr.GetResponse();
postStream = wResp.GetResponseStream();
StreamReader postReader = new StreamReader(postStream);
results = postReader.ReadToEnd();
postReader.Close();
postStream.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error in MakePostRequest: " + ex.Message);
}
return results;
}
The information in that blog is incorrect, it does not work and it is unsupported by Yammer. I'd advise you pre-obtain the token using a service account, store it somewhere safe, then pass it as an Authorization header in your POST and/or GET request. A very good example is shown here - http://blogs.technet.com/b/israelo/archive/2015/02/24/consuming-yammer-restful-api-with-angularjs-for-dummies.aspx
I have managed to successfully read my Facebook account by using the following code:
IAuthorizationState authorization = client.ProcessUserAuthorization();
if (authorization == null)
{
// Kick off authorization request
client.RequestUserAuthorization();
}
else
{
var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
Session["access_token"] = authorization.AccessToken;
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
var graph = FacebookGraph.Deserialize(responseStream);
this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
}
}
}
I am now trying to POST to my Facebook news feed and I am struggling to find a guide to help me through it. I have tried to start it myself and for some reason it seems to throw back a 400: Bad Request error.
var request = WebRequest.Create("https://graph.facebook.com/me/feed?");
var postdata = "message=hello";
postdata += "&access_token" + Session["access_token"].ToString();
var data = Encoding.ASCII.GetBytes(postdata);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Can anyone help me understand why my code is returning the error?
Use http://facebooksdk.net/ to make your job simple. Store access token and reuse for every request till it gets expired.