Failing to retrieve access token in .NET desktop app - c#

I'm writing a .NET app that runs on a Windows computer. It is not accessible through the browser. The problem is, I can't authenticate like I should. I'm currently coding in C# .NET, more specific in C#.
I have a webbrowser control on my form.
The user logs on to facebook through this webbrowser control.
After the logon, I start the authentication procedure.
I then retreive a code.
Here's where it goes wrong. With this code I want to obtain an access token.
The generated request URL looks like: https://graph.facebook.com/oauth/access_token?client_id=____MY_APP_ID______&redirect_uri=http://localhost/&client_secret=_____MY_APP_SECRET_____&code=____MY_RETREIVED_CODE_____ and is made through the code below.
Please note that my redirect URL is http://localhost. This should be okay, right?
Also, in my App Settings, I have the following information.
Site URL: http://localhost/
Site Domain: localhost
private String ExchangeCodeForToken(String code, Uri redirectUrl)
{
var TokenEndpoint = new Uri("https://graph.facebook.com/oauth/access_token");
var url = TokenEndpoint + "?" +
"client_id=" + _AppID + "&" +
"redirect_uri=" + redirectUrl + "&" +
"client_secret=" + _AppSecret + "&" +
"code=" + code;
var request = WebRequest.CreateDefault(new Uri(url));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (var responseReader = new StreamReader(responseStream))
{
var responseText = responseReader.ReadToEnd();
var token = responseText.Replace("access_token=", "");
return token;
}
}
}
}
When I execute this, I get this error:
error http://www.imageupload.org/getfile.php?id=50131&a=447f6fcc0ebd4d3f8e8a59a3a6e36ac3&t=4de0841c&o=0889D68FDC35508BA2C6F2689FCBAB7C30A8670CC9647EE598701D8BEC13ED278F0989D393&n=autherror.png&i=1
Webexception was unhandled by user code
The remote server returned an error: (400) Bad Request.
Here's where I think I might be going wrong:
Are my app settings correct?
Should my redirect url be http://localhost, even if there isn't actually a service listening there?
Most importantly:
how do I get rid of this error and retreive the access token?
Thanks in advance!

You get this error because you are not supposed to call this URL from a Desktop app : as far as I know, you can not use the token endpoint for Desktop app authentication. Also, you can get the access token directly (no need to ask for a code first). Here is what you have to do.
Load the following URL in your embedded web browser :
https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID&
redirect_uri=https://www.facebook.com/connect/login_success.html
The user will be asked to log in and will be redirected to this URL with the access token in the URL :
https://www.facebook.com/connect/login_success.html#access_token=...
So you have to detect the redirect and retrieve the access token from the URL.

Thanks quinten!
However, I've managed to solve my own problem by using the C# Facebook SDK.
This software development kit has been a really great help!
There are a lot of samples included (including authorisation)
Anyone who programs in .NET with facebook should check it out! Coding for facebook is now much easier.
http://facebooksdk.codeplex.com/

Related

Invalid PUT method from Webforms to Web API 2 (Azure)

I have a Web API in my Azure server and I'm making calls from an ASP.NET Webforms website.
I seem to be able to perform GET with no trouble. Now for the PUT, it's giving me this error:
The page you are looking for cannot be displayed because an invalid
method (HTTP verb) is being used
I was not able to DELETE either. I see some other topics where people disable some WebDav and stuff on their IIS servers and it works. But on Azure?
Below my code for the PUT:
HttpResponseMessage response = client.GetAsync("api/People/" + id).Result;
if (response.IsSuccessStatusCode)
{
var yourcustomobjects = response.Content.ReadAsAsync<People>().Result;
Uri peopleUrl = response.Headers.Location;
yourcustomobjects.name= "Bob";
response = await client.PutAsJsonAsync(peopleUrl, yourcustomobjects);
tbDebug.Text += await response.Content.ReadAsStringAsync();
}
Alright I grew tired of trying to fix this issue by enabling PUT.
So what I did, was I wrote a GET that makes the needed change in the database.
Cheers

How to push to Bitbucket repository with access token?

I used to get the access token from Bitbucket
(with the help of this documentation https://confluence.atlassian.com/display/BITBUCKET/OAuth+on+bitbucket#OAuthonbitbucket-ObtaininganOAuthConsumer)
so I want to pull/push from the logged in user's repository.
How can I use the Bitbucket REST APIs to do that with C# from an ASP.NET MVC application? I would like to implement my logic with the help of this documentation:
https://confluence.atlassian.com/display/BITBUCKET/Use+the+Bitbucket+REST+APIs
I know there is a way to list a user repo with HTTP Authentication like this:
string url = "https://bitbucket.org/api/1.0/user/repositories/";
var request = WebRequest.Create(url) as HttpWebRequest;
string credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("username" + ":" + "password"));
request.Headers.Add("Authorization", "Basic " + credentials);
using (var response = request.GetResponse() as HttpWebResponse)
{
var reader = new StreamReader(response.GetResponseStream());
string json = reader.ReadToEnd();
}
But how can I use the token value and secret to push/pull to repository?
Thank you very much!
Looking at the Documentation you sent, https://confluence.atlassian.com/display/BITBUCKET/repositories+Endpoint+-+1.0 - you cannot push/pull to the repository with the API, instead you use the normal way to interact with the git repo - using a commandline tool or whatnot.
You may only alter the meta-data through the API: https://confluence.atlassian.com/display/BITBUCKET/repository+Resource+1.0#repositoryResource1.0-PUTarepositoryupdate
So just use the API client that is commandline: git

Dwolla oauth access token in windows app

I am creating a windows 8 metro app but I am having trouble with getting the oauth2 access token. I can get the temporary code with this code just fine:
Uri requestUri = new Uri(string.Format(AUTH_URL + "?client_id={0}&response_type=code&scope={1}&client_secret={2}&redirect_uri={3}", CLIENT_ID, string.Join("|", scopeList.ToArray()), CLIENT_SECRET, WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri));
WebAuthenticationResult result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, requestUri);
But when I try to use that code to get the permanent access token, it either gives me an Internal Server Error (500) or times out. It gives me a 500 when I don't have a redirect_uri, so I keep it in. Otherwise my request just times out with no response with this code:
private const string TOKEN_URL = "https://www.dwolla.com/oauth/v2/token";
Uri requestUri = new Uri(string.Format(TOKEN_URL + "?client_id={0}&client_secret={1}&grant_type={2}&code={3}&redirect_uri={4}", CLIENT_ID, CLIENT_SECRET, GRANT_TYPE, code, WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri)));
WebAuthenticationResult result = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.SilentMode, requestUri);
All of my strings are uri escaped. I just don't know what I am doing wrong.
Using anything besides the WebAuthenticationOptions.SilentMode option just shows a loading browser window
Also I can't use OAuth libraries that are made for C# because they use .NetFramework while Windows 8 Apps use .NetCore, a trimmed down version.
Any help would be great
The requestUri looks different between the temporary code and the redirect permananent access token. It needs to be the exact same thing.

400 bad request invalid hostname only in android application

I have a asp.net mvc website deployed on a server, providing a few web interfaces to others. For example, getting the current user's information, my test C# console application looks like this:
using (var client = new WebClient())
{
try
{
var url = "http://api.fake.mysite.com/v1.0/user/current";
var token = "e0034e1c082de62b74e361b15f9c6471";
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(token));
client.Headers["Authorization"] = encoded;
client.Headers["Content-Type"] = "application/json";
Console.WriteLine(client.DownloadString(url));
}
catch (WebException e)
{
//log the exception
}
}
You can see the usage is pretty simple, just request the url via HTTP_GET, set the Authorization header to the encoded token. Actually it works fine in my machine. But some one else meets a strange issue when visiting this url in an android application, here is the java code:
HttpClient httpClient = new DefaultHttpClient();
String token = "e0034e1c082de62b74e361b15f9c6471";
String url = "http://api.fake.mysite.com/v1.0/user/current";
HttpGet httpGet = new HttpGet(url);
String encoded = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);
httpGet.addHeader("Authorization", encoded);
httpGet.addHeader("Content-Type", "application/json");
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
int responseCode = httpResponse.getStatusLine().getStatusCode();
String response = EntityUtils.toString(httpResponse.getEntity());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
then he got "400 bad request invalid host name" error. I've tried:
(1) make sure the variable "encoded" has the same value in C# and Java code.
(2) make sure the website's domain name is correctly set in server IIS
(3) all PCs/mobile phones can visit the test index page(http://api.fake.mysite.com)
(4) ping api.fake.mysite.com works fine
(5) if removing httpGet.addHeader("Authorization", encoded);, the Java program got a 401 Unauthorized result as expected(the server code under my control returns the result)
(6) some other applications using C# and PHP can use the web methods well, only android application can't(tested in two totally different android mobile phones, the android emulator got 400 invalid host name either)
(7) use IP instead of domain name http://xx.xx.xx.xx/v1.0/user/current, everything is the same. (xx.xx.xx.xx stands for the ip address)
(8) checked the IIS log, all requests to /v1.0/user/current returns 200/401/500, no 400 results.
(9) make sure the android application has internet permissions(actually we've added all permissions)
Does anyone know the reason or help to find the reason? Thank you very much, this issue is driving me crazy.
Should be httpGet.addHeader("Authorization", "basic " + encoded); and String encoded = Base64.encodeToString(token.getBytes(), Base64.NO_WRAP);
I struggled the very same problem. I can send HTTP POST from Fiddler or any other tool to my asp.net web API in debug mode but I can not access from my android application.
I tried to be sure to connect from my computer browser to
web API interface.
I tried to be sure to connect from android emulator web
browser(AEWB). And then I deployed my web api to IIS so I can get certain address to access from AEWB.
I can accessed to this adres from my AEWB
http://10.0.0.2:8088/api/tran
http://10.0.0.2 -> this is your local host address seen from Android
8088 -> this is your port of web api hosted on IIS
/api -> this is web api
/tran -> this is your controller

WebClient failing on physical device and emulator

UPDATE:
Maybe it's just me not understanding how oAuth works? I tried running
the query manually on http://www.apikitchen.com and I get a 400 error
there too! Just to be sure, am I constructing the URL correctly here?
POST URL:
https://api.bufferapp.com/1/oauth2/token.json?client_id=[hidden]&client_secret=[hidden]&redirect_uri=http://apps.joel-murphy.com/buffer/code/success.php&code=[the
access code I get from buffer starting with
1/]&grant_type=authorization_code
Original post:
I'm building a Windows Phone application which requires the use of data from a website. The website uses oAuth to authenticate users.
I used the built in web browser control to make a GET request to authenticate users. The official documentation requires the URL structure to be like this:
GET https://bufferapp.com/oauth2/authorize?
client_id=...&
redirect_uri=...&
response_type=code
This part of my app works. Although when it comes to exchanging the Authorization token for an access token from the server, I am facing problems. The official documentation requires the URL structure to be like this:
POST https://api.bufferapp.com/1/oauth2/token.json?
client_id=...&
client_secret=...&
redirect_uri=...&
code=...&
grant_type=authorization_code
Correct me if I'm wrong, but from what I know there is no way to make a POST request from a browser, unless submitting a form. For this reason, I have decided to use the WebClient class to submit data to the server. However, no matter if I run my code on an actual device or on the Visual studio emulator I always receive the following error:
The remote server returned an error: NotFound
Does anyone have any idea what's wrong with the following code? I've spent over 5 hours across 2 days trying to solve this error, but nothing seems to be working.
The code I'm using:
WebClient wc = new WebClient();
wc.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
wc.UploadStringAsync(new Uri(access_token_url), "POST", GetPostParameters());
void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
MessageBox.Show(e.Result);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
string GetPostParameters()
{
string data = "";
data += "client_id="+client_id + "&";
data += "client_secret=" +client_secret + "&";
data += "redirect_uri=" + redirect_uri+ "&";
data += "code=" + App.AccessToken + "&";
data += "grant_type=authorization_code";
return data;
}
Does anyone have any idea what's wrong? this is driving me crazy and it's a real shame that oauth has to be so complicated when it's such a used technology nowadays.
Thanks in advance.
Can you try URL-encoding the redirect_uri variable?

Categories