C#: Error 403 while authenticating user on twitter C# - c#

Hello I am making a GUI application on which a user gives his USER ID and Password to login on twitter.
I have the following code but it's not working for me, giving an error of 403 Forbidden
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
// encoding username/password
string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(txtId.Text + ":" + txtPassword.Text));
//connect with verify page
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://api.twitter.com/1.1/account/verify_credentials.xml");
// HttpWebRequest request =(HttpWebRequest)WebRequest.Create("http://twitter.com/account/verify_credentials.xml");
// setting method to GET- This API expects a GET method Call
request.Method = "POST";
// setting authorization levels
request.Headers.Add("Authorization", "Basic " + user);
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
//request.ContentType = "application/x-www-form-urlencoded";
// set the response from the GET command
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
// collect info returned from the GET call
string tempStream = null;
int count = 0;
do
{
count= resStream.Read(buf, 0, buf.Length);
if(count!=0)
{
tempStream= Encoding.ASCII.GetString(buf,0,count);
sb.Append(tempStream);
}
}while(count>0);
//convert result to XML DOC
XmlDocument doc = new XmlDocument();
doc.LoadXml(sb.ToString());
// get person name from the newly created xml document
XmlNodeList nodeList = doc.SelectNodes("/user/name");
foreach (XmlNode node in nodeList)
personName = node.InnerText;
label1.Text = "Welcome, " + personName + "!";
also attached the GUI picture
need help if anyone know the solution
Thanks

Twitter no longer provide username/password access by default.
To have access to such a feature you will have to contact them privately with a very strong case (and company) so that they authorize your app to use it.
As an example the last company authorized to access this authentication was Instagram 2 years ago...
What you want to use is the OAuth mechanism to execute your query from an Application and User information.
I would suggest that you use the library that I developed for the Twitter developers using C# (https://github.com/linvi/tweetinvi).
You will be able to do what you want with the following lines of code :
Auth.SetUserCredentials("CONSUMER_KEY", "CONSUMER_SECRET", "ACCESS_TOKEN", "ACCESS_TOKEN_SECRET");
var authenticatedUser = User.GetAuthenticatedUser();
label1.Text = "Welcome, " + authenticatedUser.Name + "!";

Related

Redirect from 1 site to another bypassing the login page

I have to websites - A (written in C# using ASP.NET Web Forms) and B (written in VB using ASP.NET MVC4). Both websites are on different domains, require logging into and do not share the same database. I need to make sure that the users of website A could get access to website B without the need to authenticate on website B.
My proposed solution may not be what you would call a "best practice". I decided to set up a fictitious user on website B, whose credentials and permissions would be used by the users of website A (without their knowledge - hence bypassing the Login Page on website B).
I have the following API request in the code of website A:
HttpWebRequest post = (HttpWebRequest)WebRequest.Create("http://siteB/api/WebsiteA/Authenticate/");
post.Method="POST";
post.KeepAlive = true;
string postData = "email=" + email + "&password=" + password + "&hash=" + hash + "&timestamp=" + timestamp + "&returnUrl=" + returnUrl;
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
post.ContentType = "application/x-www-form-urlencoded";
post.ContentLength = byteArray.Length;
Stream dataStream = post.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = post.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
JavaScriptSerializer js = new JavaScriptSerializer();
Dictionary<string, string> d = new Dictionary<string, string>();
d = js.Deserialize<Dictionary<string, string>>(responseFromServer);
if (d.First().Value == "ok")
{
HttpContext.Current.Response.Cookies.Add(cookie_AU);
HttpContext.Current.Response.Cookies.Add(cookie_UD);
HttpContext.Current.Response.Cookies.Add(cookie_UL);
HttpContext.Current.Response.Redirect(returnUrl);
}
reader.Close();
dataStream.Close();
response.Close();
On website B I have the following Handler:
Public Class WebsiteAController
Inherits ApiController
<HttpPost()> _
Public Function Authenticate(params As API_AuthModel) As HttpResponseMessage
Try
Dim Result As New API_JSONResult
' Authenticate the message
Dim Auth As New API_Auth
If Auth.AuthenticateMessage(params.Hash, params.Timestamp, params.Email) Then
' If authentication is successful
If Membership.ValidateUser(params.Email, params.Password) Then
Result.status = "ok"
Result.message = SystemAuth.GenerateNewToken() 'token
Else
Result.status = "invalid"
Result.message = "Invalid authentication credentials"
End If
Else
Result.status = "error"
Result.message = "Invalid message"
End If
' Ensure the result is returned as JSON without further serialisation as this has been done already
Dim ResponseMsg = New HttpResponseMessage()
ResponseMsg = ControllerContext.Request.CreateResponse(HttpStatusCode.OK, Result)
ResponseMsg.Content.Headers.ContentType = New MediaTypeHeaderValue("application/json")
Return ResponseMsg
Catch ex As Exception
Return New HttpResponseMessage(HttpStatusCode.NotFound)
End Try
End Function
Unfortunately I have come to understand that this is not working. The main problem being that after my users authenticate successfully, they are not "remembered" as authenticated on website B. And the cookies I add to the response from website A do not seem to help either. I get redirected to the login page on website B. Am I doing something majorly wrong here? People have vaguely mentioned to me that API is stateless, and that I need to pass the Session_ID. If that is the case, how could I get the Session_Id and pass it between the two websites?
If you have any better suggestions/criticism please do share. I am very very new to API and I have spent my last 3 weeks attempting different solutions. It is very likely that I have understood how API works all wrong.

Insert photo ERROR: The remote server returned an error: (403) Forbidden

I need your help!.
Im trying to insert a new photo into a Picasa Album using Oauth 2.0 and a simple HttpRequest process. The result is that I cant insert a new photo into my Picasa web album after following the instructions listed on: https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol#Auth
I also have to say that I tried using the .Net library that they provide with the same results.
The implementation that I'm using now is the following:
public static string PostImage(
string streamImageConvertedToString)
{
string url = string.Format("https://picasaweb.google.com/data/feed/api/user/{0}/albumid/{1}", "username#gmail.com", "idAlbum");
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ContentType = "image/jpeg";
request.ContentLength = Encoding.UTF8.GetByteCount(data);
request.Method = "POST";
request.Headers.Add("GData-Version", "2");
request.Headers.Add("Slug", "cute_baby_kitten.jpg");
request.Headers.Add("Authorization", "Bearer " + GetToken());
if (data != null)
{
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(data);
}
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
return result;
}
private static string GetToken() {
const string ServiceAccountEmail = "someid#developer.gserviceaccount.com";
var servicio = new PicasaService(null);
var certificate = new X509Certificate2(HttpContext.Current.Server.MapPath("/key2.p12"), "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountCredentialInitializer =
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { "https://picasaweb.google.com/data/" }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
return credential.Token.AccessToken;
}
Any help is welcome!!
(403) Forbidden
Means that you are trying to use a method insert which requires authorization to do.
you are connecting to service account someid#developer.gserviceaccount.com which should give you access to someid#developer.gserviceaccount.com pictures then.
you appear to be trying to access username#gmail.com unless you have given someid#developer.gserviceaccount.com access to insert pictures on behalf of username#gmail.com (Which I am not even sure is possible) you are not going to have permission to do this.
Remember a service account is a sudo user it has its own drive account, calendar account ... it does not have access to a random users data unless that user has given them access like they would any other user.
Note: Google .net client library does not support gdata APIs. Picasa is a gdata library I like how are trying to merge the two I am have to test this.
You're best (imho) approach would be to forget libraries and forget service accounts. Get a refresh token for the google user account you're trying to insert to, and use the raw HTTP REST API to invoke Picasa.

OAuth With Twitter On C# .NET

Simply put, I'm trying to create a webpage with Visual Studio 2012 wherein the user will log into a page, which, when authorized, will post a tweet, and enable them to use the rest of the features on the page. I'd like to remember said users credentials to also limit the rate at which they use a certain feature.
The problem is, I have been searching for days and I am unable to find an UP TO DATE and working example for me to follow. Everything seems to be outdated. (Twitterizer ; TweetSharp) I've switched from Java to C# & .NET and still no progress.
I am now seeking direct help.. Code snippets .. Tutorials .. Anything .. So that I can accomplish this task. I'm new to .NET but used to Java & C/C++ so I don't expect to be confused by too trivial of code..
My exact request is to be able to log in with twitter, save credentials (or the user's access token, whatever) & post a tweet.
This is a basic example of how to authenticate and retrieve a user's timeline:
// You need to set your own keys and screen name
var oAuthConsumerKey = "superSecretKey";
var oAuthConsumerSecret = "superSecretSecret";
var oAuthUrl = "https://api.twitter.com/oauth2/token";
var screenname = "aScreenName";
// Do the Authenticate
var authHeaderFormat = "Basic {0}";
var authHeader = string.Format(authHeaderFormat,
Convert.ToBase64String(Encoding.UTF8.GetBytes(Uri.EscapeDataString(oAuthConsumerKey) + ":" +
Uri.EscapeDataString((oAuthConsumerSecret)))
));
var postBody = "grant_type=client_credentials";
HttpWebRequest authRequest = (HttpWebRequest)WebRequest.Create(oAuthUrl);
authRequest.Headers.Add("Authorization", authHeader);
authRequest.Method = "POST";
authRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
authRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using (Stream stream = authRequest.GetRequestStream())
{
byte[] content = ASCIIEncoding.ASCII.GetBytes(postBody);
stream.Write(content, 0, content.Length);
}
authRequest.Headers.Add("Accept-Encoding", "gzip");
WebResponse authResponse = authRequest.GetResponse();
// deserialize into an object
TwitAuthenticateResponse twitAuthResponse;
using (authResponse)
{
using (var reader = new StreamReader(authResponse.GetResponseStream())) {
JavaScriptSerializer js = new JavaScriptSerializer();
var objectText = reader.ReadToEnd();
twitAuthResponse = JsonConvert.DeserializeObject<TwitAuthenticateResponse>(objectText);
}
}
// Do the timeline
var timelineFormat = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={0}&include_rts=1&exclude_replies=1&count=5";
var timelineUrl = string.Format(timelineFormat, screenname);
HttpWebRequest timeLineRequest = (HttpWebRequest)WebRequest.Create(timelineUrl);
var timelineHeaderFormat = "{0} {1}";
timeLineRequest.Headers.Add("Authorization", string.Format(timelineHeaderFormat, twitAuthResponse.token_type, twitAuthResponse.access_token));
timeLineRequest.Method = "Get";
WebResponse timeLineResponse = timeLineRequest.GetResponse();
var timeLineJson = string.Empty;
using (timeLineResponse)
{
using (var reader = new StreamReader(timeLineResponse.GetResponseStream()))
{
timeLineJson = reader.ReadToEnd();
}
}
public class TwitAuthenticateResponse {
public string token_type { get; set; }
public string access_token { get; set; }
}
Please see here (The github project has asp.net and asp.net mvc examples):
Authenticate and request a user's timeline with Twitter API 1.1 oAuth
I created an an open source project for it but unfortunately it doesn't yet include the ability to send tweets. I don't think it would be difficult but I am short on time at the moment.
If I was to implement it I would find out exactly what needs to be posted by the api, as detailed here:
https://dev.twitter.com/docs/api/1.1/post/statuses/update
For the assisting of other persons who have fallen into the same gap I did... Check out this site
It will help with authenticating & signing in & retrieving basic information.

How to handle Invitation API of Linkedin in c# Asp.NET

Can any one guide me how to tackle with Linkedin Invitation API in c# asp.net. I want to send invitation to particular user from my app via this api, but don't find any sufficient information to start it. Can any one give me some example to start with. I have already get list of users from linkedin search api. Now i want to send invitation to those users.
Thanks in advanced. Hope best answer will come out.
Thanks
Finally, it's done. I have successfully implement linkedin invitation api with asp.net c#.
I am posting sample code here, for other users who want to implement it.
try
{
string uid=uniqueid of user,to whom you want to send request.
// if you get this user bysearch api or 1st connection, then from http-header response, you will find value field. split this value by ':' and store in two variable
string name=splitvalue1;
string namevalue=splitvalue2;
string xml = "<?xml version='1.0' encoding='UTF-8'?><mailbox-item><recipients><recipient><person path=\"/people/id=" + uid + "\" /></recipient></recipients>";
xml += "<subject>Invitation to Connect</subject>";
xml += "<body>Please join my professional network on LinkedIn.</body>";
xml += "<item-content><invitation-request><connect-type>friend</connect-type><authorization><name>" + name + "</name><value>" + namevalue + "</value></authorization></invitation-request></item-content></mailbox-item>";
string accessCodeUri = "https://api.linkedin.com/v1/people/~/mailbox?oauth2_access_token=" + Session["accessCode"]; // this is session value which you get on authorization success return by linkedin
WebRequest request = WebRequest.Create(accessCodeUri);
request.Method = "POST";
request.ContentType = "application/xml";
request.ContentLength = xml.Length;
StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
requestWriter.Write(xml);
requestWriter.Close();
WebResponse webResponse = request.GetResponse();
//success
}
catch(WebException exc)
{
}
Hope it helps other.

facebook c# sdk - The user hasn't authorized the application to perform this action

I am building a console app that will publish streams to a page's wall.
Issue: I'm getting "The user hasn't authorized the application to perform this action". I'm using opengraph to get the access token.
Am I missing something? Any help is greatly appreciated. Thanks!
// constants
string apiKey = "XXX";
string secret = "XXX";
string pageId = "XXX";
// get access token
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials", apiKey, secret); // todo: figure out open graph url
WebRequest req = WebRequest.Create(url);
WebResponse resp = req.GetResponse();
StreamReader reader = new StreamReader(resp.GetResponseStream());
string respStr = reader.ReadToEnd();
string accessToken = respStr.Replace("access_token=", "");
// construct the post
dynamic messagePost = new ExpandoObject();
messagePost.access_token = accessToken;
messagePost.picture = "www.google.com/pic.png";
messagePost.link = "www.google.com";
messagePost.name = "some name";
messagePost.captiion = "some caption";
messagePost.description = "some description";
messagePost.req_perms = "publish_stream";
messagePost.scope = "publish_stream";
// using client
FacebookClient client = new FacebookClient(accessToken);
try // to post the post to the page's wall
{
var result = client.Post(string.Format("/{0}/feed", pageId), messagePost);
}
catch (FacebookOAuthException ex)
{
// getting caught here, with error msg = "The user hasn't authorized the application to perform this action"
}
catch (FacebookApiException ex)
{
// ignore
}
After visiting the following links, I was able to run the code and have it successfully publish to the page's wall, after which it shows up in the Likers' news feeds.
http://www.facebook.com/login.php?api_key={API_KEY_GOES_HERE}&next=http://www.facebook.com/connect/login_success.html&req_perms=read_stream,publish_stream
http://www.facebook.com/connect/prompt_permissions.php?api_key={API_KEY_GOES_HERE}&next=http://www.facebook.com/connect/login_success.html?xxRESULTTOKENxx&display=popup&ext_perm=publish_stream&profile_selector_ids={PAGE_ID_GOES_HERE}
Thanks to the answer on Authorizing a Facebook Fan Page for Status Updates
"Liking your application" and "allowing your application to post to his wall" are two different sentences. There is no magic wand that allows you to override a user's preference whether they like you or not.
Your best bet is to handle the "failure" and move on to the next person. If you want to know likers that don't want you to post to their wall, you can get that information in the return and store it in some type of "log".

Categories

Resources