DotNetOpenAuth LinkedIn post share error using Asp.Net MVC - oauth

DotNetOpenAuth is an amazing package. However, I keep hitting some hurdle or other. Till now most of them got solved, now I have hit a problem, which is taking up a lot of my time.
The Problem:
I want to share a post on linkedin using DotNetOpenAuth. I was able to share a few posts a while back, but all of a sudden things are now broken, and I am not able to post shares anymore. I do not recollect making much changes in my code. Can someone have a look at my diagnosis, code and see if I am messing something up?
The Diagnosis:
I ran fiddler while making requests via my code and via LinkedIn's Rest Console. Here's the Fiddler output for both scenarios:
Fiddler Output for request that was made via Rest Console provided by linkedin
POST /v1/people/~/shares HTTP/1.1
Authorization: OAuth oauth_consumer_key="{consumer_key}",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1362258084",oauth_nonce="-141812272",oauth_version="1.0",oauth_token="{access_token}",oauth_signature="HBMUfvHYJAxz%2BszxStVJ%2BhfQPEQ%3D"
Host: api.linkedin.com
Content-Length: 645
X-Target-URI: http://api.linkedin.com
Content-Type: application/xml
Connection: Keep-Alive
<?xml version="1.0" encoding="UTF-8"?>
<share>
<comment>test comment</comment>
<content>
<title>test title</title>
<submitted-url>{my_test_url}</submitted-url>
<submitted-image-url>{my_image_url}</submitted-image-url>
</content>
<visibility>
<code>anyone</code>
</visibility>
</share>
Fiddler output for request that was made via my code(using DNOA):
POST http://api.linkedin.com/v1/people/~/shares HTTP/1.1
Authorization: OAuth oauth_token="{access_token}",oauth_consumer_key="{my_consumer_key}",oauth_nonce="ECYFLc0l",oauth_signature_method="HMAC-SHA1",oauth_signature="FobR745YkMlmBpOqoTDr8CwGZIQ%3D",oauth_version="1.0",oauth_timestamp="1362263560"
Content-Type: application/xml
Host: api.linkedin.com
Content-Length: 510
Connection: Keep-Alive
<?xml version="1.0" encoding="UTF-8"?>
<share>
<comment>test comment</comment>
<content>
<title>test title</title>
<description>test description</description>
<submitted-url>{my_test_url}</submitted-url>
<submitted-image-url>{my_image_url}</submitted-image-url>
</content>
<visibility>
<code>anyone</code>
</visibility>
</share>
More details:
I know that I need to pass scope while performing oauth authentication, so already have this in place. I also get proper permission prompt that reads "NETWORK UPDATES Retrieve and post updates to LinkedIn as you" when user is authorizing my application
Do note that I do get an access token, and I am able to perform some read operations, like for getting user details using this token, however, I am not able to use the token to share posts on LinkedIn. Currently the implementation is using LinkedIn oAuth 1.0a.
Here's my code block as well:
public bool PostToLinkedIn(WebConsumer consumer, string sShareMessageXml, string accessToken = null)
{
var payload = Encoding.ASCII.GetBytes(sShareMessageXml);
AuthorizedTokenResponse token = null;
bool bIsAccessTokenSupplied = !string.IsNullOrEmpty(accessToken);
if (!bIsAccessTokenSupplied)
{
token = consumer.ProcessUserAuthorization();
}
if (token != null || bIsAccessTokenSupplied)
{
this.AccessToken = bIsAccessTokenSupplied ? accessToken : token.AccessToken;
var resourceEndpoint = new MessageReceivingEndpoint("http://api.linkedin.com/v1/people/~/shares", HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.AuthorizationHeaderRequest);
HttpWebRequest request = consumer.PrepareAuthorizedRequest(resourceEndpoint, AccessToken);
request.ServicePoint.Expect100Continue = false;
request.Method = "POST";
request.ContentLength = payload.Length;
request.ContentType = "application/xml";
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(payload, 0, payload.Length);
}
var response = consumer.Channel.WebRequestHandler.GetResponse(request);
var responseData = response.GetResponseReader().ReadToEnd();
var xmlData = XDocument.Parse(responseData);
if (xmlData.Elements(XName.Get("update")).Any())
{
return true;
}
}
return false;
}
Please let me know if you need more details. Any help would be great.
I have posted a brief version of the same problem on DNOA's google group as well here. Hopefully someone has faced this issue and has a solution.

Related

BigCommerce oAuth auth token request always returning 401

I can not figure out what I'm doing wrong. I'm developing an App for BigCommerce and can not get the simple oAuth exchange to work correctly.
The initial get request is being made to https://www.my-app.com/oauth/bigcommerce/auth. This is the code in the controller for that request. It's a Laravel 5.6 app:
use Illuminate\Http\Request;
use Bigcommerce\Api\Client as Bigcommerce;
class BigcommerceOAuthController extends Controller
{
public function auth(Request $request)
{
$object = new \stdClass();
$object->client_id = 'my-client-id';
$object->client_secret = 'my-client-secret';
$object->redirect_uri = 'https://my-app.com/oauth/bigcommerce/auth';
$object->code = $request->get('code');
$object->context = $request->get('context');
$object->scope = $request->get('scope');
$authTokenResponse = Bigcommerce::getAuthToken($object);
$storeHash = str_replace('stores/', '', $request->get('context'));
Bigcommerce::configure(array(
'client_id' => 'my-client-id',
'auth_token' => $authTokenResponse->access_token,
'store_hash' => $storeHash
));
echo "<pre>";
print_r($authTokenResponse);
print_r(Bigcommerce::getTime());
echo "</pre>";
}
}
Every time I try to install my draft app from the BigCommerce control panel, I get an error because $authTokenResponse is not an object. When I debug further into the Bigcommerce\Api\Connection class, I can see that the response from the server is empty, and the status is a 401, which means "Unauthorized".
I can't figure out why I am getting this error. As far as I can see, I'm doing everything right. I've tried urlencoding the string retrieved from $request->get('scope'), since that string becomes unencoded by Laravel, but that didn't seem to help.
I am also confused how this is even supposed to work at all. In the BigCommerce docs, they show this example POST request, which uses application/x-www-form-urlencoded Content-Type and passes the request body as a url encoded string:
POST /oauth2/token HTTP/1.1 Host: login.bigcommerce.com Content-Type:
application/x-www-form-urlencoded Content-Length: 186
client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&code=qr6h3thvbvag2ffq&scope=store_v2_orders&grant_type=authorization_code&redirect_uri=https://app.example.com/oauth&context=stores/{STORE_HASH}
However, if you inspect what's going on in the Connection class, you can see that the Content-Type is being set to application/x-www-form-urlencoded as the docs say, but the request body is being passed in as a json string, not a url string. Shouldn't the request be a url encoded string as the docs suggest?
A couple of things here to check:
Do you have a public URL where you can receive the Auth Callback?
If so, did the store owner registered the app successfully? https://developer.bigcommerce.com/api/registration
When you have the client_id and secret_id. You should have all of the details needed to send a POST request to the BC Auth Token Service at https://login.bigcommerce.com/oauth2/token
The content uses URL encode Make sure to URL encode your content. Be careful of of the encoding of & and = signs when those are actually being used as separators.
More details can be found in this post:
Can BigCommerce Private Apps use OAuth

Error 401 Unauthorized MVC .NET WEB APP

I am working with an API that wants me to send the token along with Header, specifically Content Header.
Here is my code block.
string path_current_user = "me";
var cookie = HttpContext.Request.Cookies.Get("cookietoken");
string cookie_with_token = "ACCESS_TOKEN="+cookie.Value+";";
client.DefaultRequestHeaders.Add("Cookie", cookie_with_token);
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
HttpResponseMessage response = await client.GetAsync(path_current_user);
I always get a 410 Unauthorized response. However, during debugging I can collect the values from the client object, and copy paste them into https://www.hurl.it, and I get the expected 200 OK response. So, I know the values that are being stored in the above code are correct. Its not a credentials issue for sure.
I have looked at almost 50 different threads on stack overflow, but none of them talk about this specification situation. Doing a GET with the Header Content set. Here is a screenshot of the HURL that works just fine.
Update 1 - Here is the API documentation for what I am trying to achieve.
Endpoint
GET me
Request Route
GET me
Headers
Content-Type: application/json Cookie: ACCESS_TOKEN="token characters
come here and remove the quotes"; Host: x.x
Update 2 - One of my mentors, recommended the following.
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://small-project-api.herokuapp.com/me");
request.Headers.Add.("Content-Type", "application/json");
request.Headers.Add.("Cookie", cookie_with_token);
var response2 = await httpClient.SendAsync(request);
var responsestring = await response2.Content.ReadAsStringAsync();
}
He is of the opinion that may be such a request, as mentioned below, simply won't work in dot net. I am all but ready to give up here.

Send Array of Api Request for Server in Soap iOS

i am using third party Exigo Api request for my app. the service says to send 2 more requests array in the body of main Soap service. Though i tried sending the 2 request in string form in the Body of the main request but i received Empty String . Help me out how should i do this . i got no solution in the manual or on any other site after googling this issue for a week i am posting this question
Exigo Api (Process Transaction Service)
POST /3.0/ExigoApi.asmx HTTP/1.1
Host: api.exigo.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://api.exigo.com/ProcessTransaction"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<ApiAuthentication xmlns="http://api.exigo.com/">
<LoginName>string</LoginName>
<Password>string</Password>
<Company>string</Company>
</ApiAuthentication>
</soap:Header>
<soap:Body>
<TransactionalRequest xmlns="http://api.exigo.com/">
<TransactionRequests>
<ApiRequest />
</TransactionRequests>
</TransactionalRequest>
</soap:Body>
</soap:Envelope>
This is the Soap request i have to process and Send Api Request Array in the body of the main request using iOS.
Thanks in Advance
Please check below link, like
let body = envelope.addChild(name: "soap:Body")
let header = body.addChild(name: "soap:Header" , attributes: ["xmlns:m" : "http://www.w3schools.com/transaction/"])
https://github.com/tadija/AEXML
We have tackle same type of issue for our mobile app. We have have implemented adapter that accepts JSON request from Mobile and then translate that into API request which is inculded in MVC Application as wsdl. Can't find any other way to do that.

Google Oauth 2.0 authentication for limited input device not working except on curl

I am trying to use a custom java application of mine to upload videos to my youtube account via an access limited device like a Raspberry pi running as a server.
For this I am using the Google Oauth 2.0 for limited input device as a reference.
I followed the steps mentioned with my custom java application, Fiddler and curl, the surprise is as follows:
All of the calls worked right as mentioned by Google Oauth 2.0 for limited input device for curl.
But issues were observed with Fiddler and my custom java app for the following call:
When I am trying to get the access token from Google server (Step 4 from Google Oauth link) by posting similar request:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=1084945748469-eg34imk572gdhu83gj5p0an9fut6urp5.apps.googleusercontent.com&
client_secret=hDBmMRhz7eJRsM9Z2q1oFBSem&
code=4/YMSlR3fSCC1NtUh073DuZKTJJ3ss&
grant_type=http://oauth.net/grant_type/device/1.0
but instead of getting the 'access_token' as response I am getting the following :
Status Code:400 Response: { "error" : "invalid_request",
"error_description" : "Required parameter is missing: grant_type" }
Note : With or without url encoding, my problem stays the same.
I am unable to understand what the issue is with my custom java app or with fiddler, Please help.
Following are my fiddler requests:
(One can get oauth credentials (client_id and client_secret) by following this)
Fiddler request:
(url encoded, obscured client secret)
POST HTTP/1.1
https://accounts.google.com/o/oauth2/token?client_id=308065994473-ur9dd7003ajs6mvr5s4kqnugr6j8tsf2.apps.googleusercontent.com&client_secret=XXXXXXXXXXXXXXX&code=4%2FWR-qiTquqB0e4-0LCy0-7rZ2kkE2&grant_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fdevice%2F1.0
Content-Type: application/x-www-form-urlencoded
(non url encoded, obscured client secret)
POST HTTP/1.1
https://accounts.google.com/o/oauth2/token?client_id=308065994473-ur9dd7003ajs6mvr5s4kqnugr6j8tsf2.apps.googleusercontent.com&client_secret=XXXXXXXXXXXXXX&code=4/WR-qiTquqB0e4-0LCy0-7rZ2kkE2&grant_type=http://oauth.net/grant_type/device/1.0
Java code project is available at (maven project, check the test case for the Oauth calls):
https://docs.google.com/file/d/0B8ltWBtPF-DVMDZFNHNMZXpCQlk
The parameters need to be added in the http post request body not in the url, Google documentation is confusing on this part.
public synchronized HttpResponse executePOST(HttpEntity httpEntity, String path) throws IOException {
if (!parameters.isEmpty()) {
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
}
httpPost = new HttpPost(path);
logger.info(target.toHostString());
logger.info(httpPost.getURI().toString());
logger.info(httpPost.getRequestLine().toString());
for (Header header : headers) {
logger.info(header.getName() + ": " + header.getValue());
httpPost.addHeader(header);
}
httpResponse = httpClient.execute(target, httpPost);
return httpResponse;
}

YouTube API 2.0 resumable upload - error 500

I'm using YouTube API 2.0 in iOS app and I have made request like this:
POST http://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads
Authorization = "Bearer <acess_token>";
"Content-Length" = 516;
"Content-Type" = "application/atom+xml; charset=UTF-8";
"GData-Version" = 2;
Slug = "testVideo.mov";
"X-GData-Key" = "key=<api_key>";
with body:
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:yt="http://gdata.youtube.com/schemas/2007">
<media:group>
<media:title type="plain">My title</media:title>
<media:description type="plain">My description</media:description>
<media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">Entertainment</media:category>
<media:keywords>mediawork</media:keywords>
</media:group>
</entry>
But the server response was with error 500 and no XML body with explanatoin. What should I do? It worked a month ago.
Thanks for reporting this issue. But per our blog post, Stack Overflow prides itself in being a destination for questions and answers, and not a place to file bug reports or feature requests. We ask that developers do not post on Stack Overflow for those sorts of things, and instead make use of the templates we have for filing a bug or filing a feature request in our existing public issue tracker. (Be sure to check the list of existing open issues before filing a duplicate.)
This issue is already reported https://code.google.com/p/gdata-issues/issues/detail?id=4396
You can track the status from there.

Resources