How do I access APIs without using NetworkCredential in C#/UWP? - web-services

I got some of the APP's APIs.
When I use the browser to access these APIs, the browser popup window tell me to fill in the username/password, Then I tried to fill out my username/password and found that I passed the verification!
Then I tried to write the code
var myClientHandler = new HttpClientHandler();
myClientHandler.Credentials = new NetworkCredential("abc", "!##");
this._client = new HttpClient(myClientHandler);
this._client.BaseAddress = new Uri("http://api.xxx.com");
var result = await this._client.GetStringAsync("some_api_foo.json");
Run well!
(We know that if there are no NetworkCredential, there will be 401 unauthorized exception)
But I found out that the official APP could access some of the APIs without the user logging in. How does it work? Does it use a public account? Or is there another way to access the APIs?

It uses Windows integrated authentication (Kerberos) to authenticate your users without asking them for credentials

Use Fiddler >check Authorization Header is present: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxx is Username:Password(Base64)
Decrypt it!

Related

WebAuthenticationBroker in a Universal App with Login With Amazon

I'm working on a new Universal App (first time) and I am trying to use Login with Amazon as my authentication provider. Amazon doesn't provide an SDK for .NET for LWA so I'm left trying to figure it out on my own.
Here is what I am doing so far:
var redirectUrl = "https://localhost/";
var baseUrl = "https://amazon.com/ap/oa?client_id=MY_CLIENT_ID&response_type=code&scope=profile";
var uri = new Uri(baseUrl);
var redirectUri = new Uri(redirectUrl);
WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, uri, redirectUri);
This gets me to the login with Amazon page just fine, and allows me to login, but handing off back seems to be a problem.
Any and all help appreciated.
Amazon LWA Developer Guide
Page 25.
As I can see you missed some required parameters - scope and redirest_uri. Specify them properly and probably it will work.
For a Universal App, make sure you enable the Internet Client & Server Capability.
I haven't used WebAuthenticationBroker and you haven't provided the error message you're getting, so I have to do some guessing here...
Scanning the MSDN docs for WebAuthenticationBroker, it looks like it's meant to work with the Implicit grant flow (where an access token is returned after login/consent) vs. the Authorization grant flow (where you get back a code you must then exchange for an access token).
So if it's getting back an Authorization grant response instead of an Implicit grant response, it could be throwing an error because it's missing expected fields.
Try changing your response_type from code to token and see if that helps. If it doesn't, please post some more detail on the error you're getting.

Facebook Api Check Access Token Without Hardcoding App Secret

I'm building a manual login flow for my App which is integrating some facebook functionality.
I need to check when the current access_token of the user will expire.
The API documentary says I should do this call:
GET graph.facebook.com/debug_token?
input_token={token-to-inspect} &access_token={app-token-or-admin-token}
So I did this in C#:
Uri inspectAccessTokenUri = new Uri("http://graph.facebook.com/debug_token?input_token="+access_token+"&"); //IDK which value should have the last parameter
HttpWebRequest checkToken = (HttpWebRequest)WebRequest.Create(inspectAccessTokenUri);
var response = await checkToken.GetResponseAsync();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string data = reader.ReadToEnd();
Debug.WriteLine(data);
The last parameter should be the app-token:
BUT: Of course I looked up how to get the app-token and facebook says:
Note that because this request uses your app secret, it must never be
made in client-side code or in an app binary that could be decompiled.
It is important that your app secret is never shared with anyone.
Therefore, this API call should only be made using server-side code.
(Facebook Graph API Documentation 1.1.16)
So my question: Can I check the token without the app-token or hardcoding the app-secret?
App secret is usually used by the server-side app, we don't use it in our UWP app, it could be decompiled.
Read the official doc about FB Graph Debug-Token, this can only be used when you debug your app, for example if you want to check the metadata about a given access token, after you publish your app, your code will not relay on it.
In an UWP app, we use WebAuthenticationBroker class to connect to OAuth providers such as Facebook, Flickr, Google, and Twitter. Maintenance is need during using OAuth connections. For example, expires information is included in the access token, when we use OAuth protocol for authentication and authorization, we need to refresh the access token after it expired.
Due to these conditions, you may reconsider what you can do in an UWP app and which API you should choose.
If the app-token is expired you will get a facebook response error. And you can catch this exception to deal with the situation you want. In this way you don't need to make a request with your app secret.
You can also use fb-uwp sdk that contains AccessTokenData for authenticated users

Getting an Access Token Without User Login in Facebook Graph API?

I am working with facebook graph api rsvp_event. I am using javascript SDK. Everything works great when the user is logged in. But when the user is not logged in, it gives an error.
I need information about who is attending a public event. I now understand that I would need an access token to retrieve this information. So, my question is how do I get the access token if no user is logged in? Is it impossible or is there a workaround? Could it be done server side using app_id and client_secret?
I am developing a ColdFusion page, but I can use PHP if needed. I have support for both.
I have heard the term *offline_access_permission*. They have removed this feature. Could it be done when it was still available?
EDIT:
Could this be achieved by test user? Say, on server side I login via test user, get the event information (Just a "get" request to read who is attending an event) and then log off. On the client side I do the rest ( user login, rsvp to an event).
I don't know much about "test user" or its purpose. Can anyone confirm whether this can be achieved or not?
Thanks in advance.
Are you sure you actually need the user's access token? According to documentation here you may need:
- a generic access_token for public events (those whose privacy is set to OPEN)
- a user access_token for a user who can see the event for non-public events
- an app access_token (for non-public events, must be the app that created the event)
- a page access_token (for non-public events, must be the page that created the event)
You can get info on how to get those tokens here https://developers.facebook.com/docs/concepts/login/access-tokens-and-types/
A good idea could be to store the attending users (in the DB) when you have access to the event - when some user is logged in.
UPDATE for getting the data from FileContent.
I don't know what API response exactly you are referring to, but from my experience they are returning data:
- serialized using JSON - you need to use DeserializeJSON(), for example like this:
local.returnStruct = DeserializeJSON( local.requestResult.FileContent );
or
local.returnStruct = DeserializeJSON( local.requestResult.FileContent.toString() );
send as something similar to URI. I'm using a function to get that data:
function getStructFromQueryString( queryString ) {
var ret = StructNew();
var i = 0;
var key = '';
for(i=1; i LTE ListLen(arguments.queryString,'&'); i++) {
key = ListGetAt(arguments.queryString, i, '&');
ret[ListFirst(key,'=')] = URLDecode(ListLast(key,"="));
}
return ret;
}
Basically what you want is a refresh token that can get access tokens when the user is offline, unfortunately facebook does not provide them anymore as far as i know.
To learn more about oauth2 pleas play around with https://developers.google.com/oauthplayground/ its a very nice tool to understand the oauth2 process.

Facebook SDK .Net(C#) uploading image offline

I am using the v6 C#.Net Facebook SDK (a blog can be found http://blog.prabir.me/post/Facebook-CSharp-SDK-Writing-your-First-Facebook-Application-v6.aspx).
I need to receive access permission to offline_access from users and later on (different session) post images to that user.
I've also tried uploading images to a certain page (of mine) but couldn't.
I am providing a simple dialog for the user and accept his allow for all the credentials I am asking for "user_about_me,read_stream,user_online_presence,friends_online_presence,offline_access,publish_stream,photo_upload"
Than, in different session (restarting my application), I am creating an access token using the following method:
(using WebRequest as followed:)
var url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=client_credentials",AppId, AppSecret);
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
var myString = (new StreamReader(webResponse.GetResponseStream()).ReadToEnd());
myString = myString.Replace("access_token=", "");
However when trying to access a user, that has previously gave an offline_access credentials, using the access token I get exception thrown:
(OAuthException) An access token is required to request this resource
for a very simple request:
var fb = new FacebookClient(myString);
var result = fb.Get("/{0}/permissions", userThatGaveCredentials);
Is it possible to achieve what I am looking for and if so, what am I doing wrong?
Your code to request the access token the second time is not working. There is no reason to do this (and it wont always work anyway). You should just save the access token from when the use logs in the first time.
The error you are receiving is because your myString is null when you pass it into FacebookClient, thus the error that you are not providing an access token.
Also, you should note that offline_access is being deprecated and will be removed in a few weeks so you shouldn't build a new app that uses it anyway.

Retrieving Linkedin Group discussion posts using ColdFusion

I have been requested by a client to pull the latest posts from their LinkedIn group to one of our website pages.
I am developing using ColdFusion 9 and have been researching this for quite a few days now and decided to post my query here in the hopes that someone will be able to help me out.
I can get to the point where I have a requestToken. My understanding is that I now need to sign the request token to get the accessToken. My problem is that I need to do this behind-the-scenes. However, all the examples that I can find are redirecting the front-end user to the authorisation url to allow the user to authenticate, but I don't want the user to authenticate, I want to authenticate server-side instead.
I am trying to use the Scribe Java wrapper library. Below is the code that I have so far which gets the requestToken (as well as the authorisation url). I need someone to point me in the right direction to sign the token on the server-side code so that I can make the necessary calls to consume the Groups API (e.g. http://api.linkedin.com/v1/groups/{id}/posts?count=5&start=1)
<cfscript>
var l = {};
//The LinkedIn public and private keys for application
l.oauth_consumer_key = "[My public key]";
l.oauth_sign_key = "[My secret key]";
l.serviceBuilder = CreateObject("java","org.scribe.builder.ServiceBuilder");
l.LinkedInApiClass = CreateObject("java", "org.scribe.builder.api.LinkedInApi").getClass();
l.service = l.serviceBuilder.provider(l.LinkedInApiClass).apiKey(l.oauth_consumer_key).apiSecret(l.oauth_sign_key).callback("[My callback url]").build();
l.requestToken = l.service.getRequestToken();
l.authUrl = l.service.getAuthorizationUrl(l.requestToken);
// I NEED TO DEFINE WHAT TO DO AT THIS POINT TO SIGN THE REQUEST SERVER SIDE
...
...
</cfscript>
Kirsten is technically correct - Linked In Api's require user authentication. It's annoying because you need to authenticate to even retrieve group posts.
However there are ways round it.
With scribe you can manually create an access token. So what I would do is create a dummy user account on Linked In, authenticate that user as normal and save the returned signed credentials on your database, which you can then use to create the token:
var accessToken = createObject("java", "org.scribe.model.Token").init(
"singedTokenStringReturnBackFromLinkedIn",
"singedSecretStringReturnBackFromLinkedIn",
"oauth_token=singedTokenStringReturnBackFromLinkedIn&oauth_token_secret=singedSecretStringReturnBackFromLinkedIn&oauth_expires_in=0&oauth_authorization_expires_in=0"
);
You can then skip the authenticate part and call the api allowing you to display the group posts without the current user having to sign in:
var req = createObject("java", "org.scribe.model.OAuthRequest").init(
createObject("java", "org.scribe.model.Verb").GET,
"http://api.linkedin.com/v1/groups/123456/posts"
);
oAuthService.signRequest(accessToken, req);
I have no idea if this would violate Linked In's T&C though.
OAuth authentication is designed for the user to give their permission to the application via a login on the site (in this case LinkedIn). It is not designed for you to automatically have the user grant permission for your application.
In order to get an access token to use the LinkedIn APIs, you have to include the part of the authentication flow that sends the user to LinkedIn to give your application permission to act on their behalf, at which point you can retrieve a verifier token either via PIN (which the user inputs) or via a callback to your application.
In short, there is no way to "authenticate server-side" without having the user interact with the LinkedIn site.