Dropbox - Migrating oauth1 to oauth2 using token_from_oauth1 - c#

I have been using Dropbox via the Sharpbox toolkit for a while. It's based on oAuth1, so I have a database full of oAuth1 access tokens for my users.
I'd like to convert to the new Dropbox API, which is based on oAuth2. I see that there is a "token_from_oauth1" endpoint in Dropbox's v1 spec (reference here), but I'm not figuring out how to successfully connect to this endpoint to upgrade a user's existing token. (I'm using C#/.NET).
Can anybody point me to some sample code that shows how to create a properly authenticated call to perform this operation? I think the problem is in trying to correctly authenticate/sign the request. (All of my existing dropbox calls are done by the Sharpbox library, so I can't see how it does the authentication).
Thanks!

You can get this using a simple rest client (Like RestSharp) and doing a call like this
I'm currently doing this in a xamarin app, i use the xamarin dropbox core api to login, and get the oauth_token, oauth_consumer_key and the oauth_signature. If you managed the oauth1 flow with c# is then easy to get the oauth2 token.
var rclient = new RestSharp.RestClient("https://api.dropboxapi.com/1/");
var rrequest = new RestSharp.RestRequest("oauth2/token_from_oauth1", Method.POST);
rrequest.AddHeader("Authorization", "OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\"");
rrequest.AddParameter("oauth_consumer_key", store.GetConsumerKey());
rrequest.AddParameter("oauth_token", store.GetAccessToken());
rrequest.AddParameter("oauth_signature", String.Concat(App.DropboxAppSecret, "&", store.GetAccessTokenSecret()));
var rresponse = rclient.Execute(rrequest);
string content = rresponse.Content;

There's a library for Twitter oAuth 1.0 (see http://www.voiceoftech.com/swhitley/?p=681) that actually makes it easy to make oAuth 1.0 authenticated calls. So the code below seems to work pretty well for me:
oAuthTwitter oat = new oAuthTwitter();
oat.Token = <oauth 1.0 token>;
oat.TokenSecret = <oauth 1.0 secret>;
oat.ConsumerKey = <application key>;
oat.ConsumerSecret = <application secret>;
string resultJSON = oat.oAuthWebRequest(oAuthTwitter.Method.POST, "https://api.dropboxapi.com/1/oauth2/token_from_oauth1", null);

Related

Unable to call AWS API Gateway resources/methods through .Net Core using C#

I keep on getting the exception:
"Invalid API identifier specified".
I have double checked the keys on my AWS console and even generated a new API just to be sure for testing purposes but I keep on getting this. Below is my code.
I am able to get the account details correctly, but that's about it.
For any other call like GetModelAsync, GetResourceAsync, GetRestAPIAsync etc. , I keep on getting this exception even after entering the correct keys and ids.
Would love some guidance if someone has faced a similar issue before, documentation seems limited. AWS has dedicated Gateway API SDKs for Java, JS etc. but support seems to be limited for dot net as of now.
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk.html
I am using dot net core 3.1.0. Below is my code:
// making the credentials object using the proper access and secret key.
var awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
// getting a client object using the credentials
var apiClient = new AmazonAPIGatewayClient(awsCredentials);
var accountRequest = new Amazon.APIGateway.Model.GetAccountRequest();
var account = await apiClient.GetAccountAsync(accountRequest);

Error using AutomationManagementClient with CertificateCloudCredentials

I'm trying to start an azure runbook from a MVC app.
var cert = new X509Certificate2(Convert.FromBase64String(ConfigurationManager.AppSettings["CertBase64String"]));
var creds = new CertificateCloudCredentials(ConfigurationManager.AppSettings["SubscriptionId"], cert);
AutomationManagementClient automationManagementClient = new AutomationManagementClient(creds);
var content = automationManagementClient.Runbooks.GetAsync(<Resource group name>, ConfigurationManager.AppSettings["AutomationAccount"], <Runbook name>)
I get this error:
AuthenticationFailed: Authentication failed. The 'Authorization' header is missing.
I got this code from MSDN but I can't seem to make it work.
(The certificate is the one downloaded from here ).
I tried using TokenCloudCredentials from a Console app and that seems to work fine but I'm not sure if I can use those in the MVC app.
Any ideas how I should use AutomationManagementClient with certificate credentials? Or how to use TokenCloudCredentials in the web app?
The Automation SDK you are attempting to use uses Azure Resource Manager APIs, which do not support management certificate-based authentication. You will need to authenticate via TokenCloudCredentials. The documentation that shows management certificate support is incorrect and we will update it shortly.

Sharing Moments in GooglePlus from C#

Are there any libraries out there for C# that wrap the process of sharing moments to a user's Google+ account (or to their stream)? I'm looking for something that simply take your ClientId and ClientSecret, and maybe your apiKey along with the user's id to send some text that the user has decided to share with his/her friends.
If not, but you have an example of creating a WebRequest to accomplish the same thing, that would be much appreciated too!
I've reviewed this landing page: https://developers.google.com/+/quickstart/csharp
But I'm trying to integrate into an existing MVC5 application that already has the Auth for GooglePlus taken care of.
The correct client to be using for Google APIs is the Google .NET API Client library, available via NuGet. Additional libraries for specific APIs are required if you use more than the core library. For Plus, you need the Google.Apis.Plus.v1 package.
After you have added it to your projects and have configured an API client, writing app activities is as easy as:
/// <summary>The app activity type for ADD.</summary>
private const string ADD_ACTIVITY_TYPE = #"http://schemas.google.com/AddActivity";
// Construct your Plus Service, I'll assume a helper for here.
PlusService plusService = GetPlusService(credentials);
Moment addMoment = new Moment();
ItemScope target = new ItemScope()
{
Url = ContentUrl
};
addMoment.Type = ADD_ACTIVITY_TYPE;
addMoment.Target = target;
Moment response = null;
try
{
response = plusService.Moments.Insert(addMoment, "me",
MomentsResource.InsertRequest.CollectionEnum.Vault).Execute();
}
catch (System.AggregateException)
{
/* Occurs when the server can't be seen by Google. */
}
catch (Google.GoogleApiException)
{
/* Occurs when the server can't be seen by Google. */
}
How to authenticate a user and authorize your client for access to Google APIs in MVC can be found on this blog: ASP.NET MVC with OpenID and OAuth.
A final note, app activities require you to specify an app activities pseudo-scope (request_visible_actions) which is easier with the Sign-In button than via the framework. If you are getting 401 errors, this is the most likely culprit.

Modifying OWIN OAuth middleware to use JWT bearer tokens

I'm currently trying to create a proof of concept for claims based authentication for a new app using a combination of the following technologies: Web API 2, OWIN middleware and JWT.
To keep things simple I started with the Web API 2 project template and changed the authentication to 'Individual User Accounts'. The sample client I created was then able to get a token by calling /Token and was able to call a sample endpoint with the OAuth bearer token. So far so good. I then added the following code to Startup.Auth.cs to try and enable JwtBearerAuthentication:
var jwtOptions = new JwtBearerAuthenticationOptions
{
AllowedAudiences = audiences,
IssuerSecurityTokenProviders = new[] {
new SymmetricKeyIssuerSecurityTokenProvider(issuer, signingKey) }
};
app.UseJwtBearerAuthentication(jwtOptions);
I expected that Web API 2 would start returning JWTs from the call to /Token, but it doesn't appear to have done anything. I've been banging my head against this for a few days with no success and the Microsoft documents aren't very forthcoming.
I also tried adding the following to my OAuthAuthorizationServerOptions
AuthorizationCodeFormat = new JwtFormat(audience, new SymmetricKeyIssuerSecurityTokenProvider(issuer, signingKey))
I could also be trying to doing the completely wrong thing.
Any ideas would be greatly appreciated.
Well, now there is a setting on OAuthAuthorizationServerOptions that you can specify the format of your access token, not the authorization code, like you're doing on you example.
So, instead of:
AuthorizationCodeFormat = new JwtFormat(audience, new SymmetricKeyIssuerSecurityTokenProvider(issuer, signingKey))
You should have:
AccessTokenFormat = new JwtFormat(audience, new SymmetricKeyIssuerSecurityTokenProvider(issuer, signingKey))
The Windows Identity Foundation uses a proprietary token format, not JWT. The JWT code you see above is for consuming tokens, not generating them. There is a helpful discussion on the ASP.NET forums.
However, in the second half of 2014 Microsoft officially released support for JWT in Windows Identity foundation, with the JSON Web Token Handler. You should be able to install and use that package to solve the problem you have described.
I don't think there's any current way to override how the token is output in the response. I took a look at the OAuthAuthorizationServerHandler in the Katana source code repository.
You'll see that in the InvokeTokenEndpointAsync method, there is a section that creates a JsonTextWriter which generates the response. It is not done in such a way that any kind of extension would affect it.
I find this frustrating too. Microsoft's library should have some way to easily override the response serialization. You can't even add your own custom parameters to the response.
You can use this sample https://github.com/thinktecture/Thinktecture.IdentityModel/tree/master/samples/OAuth2/EmbeddedResourceOwnerFlow
for writting authentication logic in your project.
After it you must add [Authorize] attribute to each controller or action which requires authorization(OWIN Katana contains the logic of validating token, authorization and some other useful things).

Google Drive simple API Access authorization fail

I'm trying to authorize in google using .NET SDK provided, but it failes with "Invalid credentials" error. I found this answer
Google Calendar V3 2 Legged authentication fails
but I still don't see where is the mistake. Looks like everything is done as described.
Here is my code
const string CONSUMER_KEY = "mytestdomain.com";
const string CONSUMER_SECRET = "my_consumer_secret";
const string TARGET_USER = "user";
const string SERVICE_KEY = "some_api_key";
var auth = new OAuth2LeggedAuthenticator(CONSUMER_KEY, CONSUMER_SECRET, TARGET_USER, CONSUMER_KEY);
var service = new DriveService(auth) { Key = SERVICE_KEY };
var results = service.Files.List().Fetch();
Console.WriteLine(results.Items.Count);
and here are screenshots from google control panel. I just replaced domain name, consumer key and api key.
Screenshot from Manage API client access page
Screenshot from Manage OAuth key and secret for this domain page
Screenshot from API Access page in Google API console
OAuth 1.0 has been deprecated and 2-Legged OAuth 1.0 with it. Although it is still supported for the deprecation period if I were you I would use Service Accounts with OAuth 2.0 to perform domain-wide delegation of authority.
This is very well documented on the Perform Google Apps Domain-wide Delegation of Authority page of the Google Drive SDK documentation.

Categories