405 Method Not Allowed in DocuSign SOAP API C# Client - c#

I'm hoping that DocuSign will weigh in here. I'm using the page from the SOAP API Guide "Using DocuSign WSDL’s in the .Net Environment". I've used the CredentialsAPI to login successfully, and passed the baseURL to the constructor of the DSAPIServiceSoapClient. But I'm getting a 405 Method Not Allowed error on every call. I've tried it with the Integrator Key appended to the user name and without. I'm not sure what I'm doing wrong.
CredentialSoapClient credsClient = new CredentialSoapClient();
LoginResult login = credsClient.Login(DSAPIUsername, DSAPIPassword, true);
string auth = "<DocuSignCredentials><Username>" + DSAPIUsername + "</Username>" +
"<Password>" + DSAPIPassword + "</Password>" +
"<IntegratorKey>" + DSIntegratorKey + "</IntegratorKey>" +
"</DocuSignCredentials>";
_apiClient = new DSAPIServiceSoapClient("DSAPIServiceSoap", login.Accounts.First().BaseUrl);
_scope = new OperationContextScope(_apiClient.InnerChannel);
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("X-DocuSign-Authentication", auth);
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

I did as suggested, and I found the problem in my own code. When I looked at the error in Fiddler, the details showed "HTTP Verb used is not allowed". That's when I realized that I was POSTing to the base url, not to dsapi.asmx. That needs to be added when using the BaseURL from a login. Sorry Internets. User error.

Related

Actions on Google Request Sync returning 403

I'm working on an Actions on Google smart home device.
I'm using a service account key with the "Service Account Token Creator" role, getting a token with the official NuGet package.
This is the code I've got to create the token for the request. It's the same code for both the Report State call and Request Sync.
var oauth = global::Google.Apis.Auth.OAuth2.GoogleCredential.FromJson(jsonContent).CreateScoped("https://www.googleapis.com/auth/homegraph");
System.Diagnostics.Trace.WriteLine(".. Awaiting token");
string token = await oauth.UnderlyingCredential.GetAccessTokenForRequestAsync();
The call to the Report State API is working fine, and I can see the homegraph data updating using the Smart Home Dashboard, but I'm getting a 403 "The caller does not have permission" when trying to use it with the Request Sync API.
I'm sure I've followed the instructions at https://developers.google.com/assistant/smarthome/develop/request-sync#http-post correctly but I'm at a loss as to why this isn't working as expected.
I have read that if the actual SYNC request fails, the RequestSync will fail the same way - that is, the 403 could be actually coming from my fulfillment endpoint, however, if that were the case I should also be seeing that request in my logs, so it looks like it's not generating a SYNC request.
Also, I don't have the logs, but when I first set this up it was actually returning a success response. The problem at that time was that despite getting a success code from the homegraph, the test suite was still failing.
The rest of the code is as follows
using Google.Apis.Auth.OAuth2;
using Google.Apis.HomeGraphService.v1;
using Google.Apis.HomeGraphService.v1.Data;
var homeGraphServiceService = new HomeGraphServiceService();
var devicesResource = new DevicesResource(homeGraphServiceService);
var i = 1;
foreach (var key in keys)
{
System.Diagnostics.Trace.WriteLine(".. Building request for key " + i + " of " + keys.Length);
i++;
var requestSync = devicesResource.RequestSync(
new RequestSyncDevicesRequest
{
AgentUserId = key
});
requestSync.AccessToken = token;
try
{
System.Diagnostics.Trace.WriteLine(".. Sending request");
var _ = await requestSync.ExecuteAsync();
}
catch (GoogleApiException e)
{
System.Diagnostics.Trace.WriteLine(".. .. Request Sync returned error code: " + e.HttpStatusCode + "\n" + e.Message + "\n\n");
}
}
I also left a comment on an IssueTracker issue I found, but I'm not sure if I should be holding my breath on that one.

ASP NET Core Twitter OAuth Request Token Issues

Background
I have a back end application that has a Twitter app setup and I can query and pull user tweet/post data. This is great, however, right now on the front end I don't have full Twitter integration setup. What I mean by this is that on the front end the user can enter any Twitter username and I want to know for sure that the Twitter username entered actually belongs to the user. With a Twitter application key you can pull public Twitter data for any twitter account which works well for large scale data ingestion and in my case proof of concept kind of work. At the point I am now, I need to have the assumption enforced in the back end that the data being analyzed for a particular Twitter screen name is also owned by the user of the account on my web application.
The proposed Twitter Solution
Here is a bunch of reference documentation I have been trying to follow.
https://developer.twitter.com/en/docs/basics/authentication/guides/log-in-with-twitter
https://developer.twitter.com/en/docs/basics/authentication/api-reference/request_token
https://oauth.net/core/1.0/#anchor9
https://oauth.net/core/1.0/#auth_step1
I have been trying to follow this and I have had different permutations to the code posted below (one without the callback URL as parameters, one with etc.) but at this point, not very different. I have not had any success and it's been more than a couple of days, which is killing me.
The code
This is my attempt to follow the OAuth specification proposed above in the documentation. Note that this is ASP.NET Core 2.2 + code. Also, this is the code for just Step 1 in the Twitter guide for OAuth authentication and authorization.
public async Task<string> GetUserOAuthRequestToken()
{
int timestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
string nonce = Convert.ToBase64String(Encoding.ASCII.GetBytes(timestamp.ToString()));
string consumerKey = twitterConfiguration.ConsumerKey;
string oAuthCallback = twitterConfiguration.OAuthCallback;
string requestString =
twitterConfiguration.EndpointUrl +
OAuthRequestTokenRoute;
string parameterString =
$"oauth_callback={WebUtility.UrlEncode(twitterConfiguration.OAuthCallback)}&" +
$"oauth_consumer_key={twitterConfiguration.ConsumerKey}&" +
$"oauth_nonce={nonce}&" +
$"oauth_signature_method=HMAC_SHA1&" +
$"oauth_timestamp={timestamp}" +
$"oauth_version=1.0";
string signatureBaseString =
"POST&" +
WebUtility.UrlEncode(requestString) +
"&" +
WebUtility.UrlEncode(parameterString);
string signingKey =
twitterConfiguration.ConsumerSecret +
"&" + twitterConfiguration.AccessTokenSecret;
byte[] signatureBaseStringBytes = Encoding.ASCII.GetBytes(signatureBaseString);
byte[] signingKeyBytes = Encoding.ASCII.GetBytes(signingKey);
HMACSHA1 hmacSha1 = new HMACSHA1(signingKeyBytes);
byte[] signature = hmacSha1.ComputeHash(signatureBaseStringBytes);
string authenticationHeaderValue =
$"oauth_nonce=\"{nonce}\", " +
$"oauth_callback=\"{WebUtility.UrlEncode(twitterConfiguration.OAuthCallback)}\", " +
$"oauth_signature_method=\"HMAC_SHA1\", " +
$"oauth_timestamp=\"{timestamp}\", " +
$"oauth_consumer_key=\"{twitterConfiguration.ConsumerKey}\", " +
$"oauth_signature=\"{Convert.ToBase64String(signature)}\", " +
$"oauth_version=\"1.0\"";
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(
baseUri: new Uri(twitterConfiguration.EndpointUrl),
relativeUri: OAuthRequestTokenRoute);
request.Content = new FormUrlEncodedContent(
new Dictionary<string, string>() {
{ "oauth_callback", twitterConfiguration.OAuthCallback }
});
request.Headers.Authorization = new AuthenticationHeaderValue("OAuth",
authenticationHeaderValue);
HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request);
if (httpResponseMessage.IsSuccessStatusCode)
{
return await httpResponseMessage.Content.ReadAsStringAsync();
}
else
{
return null;
}
}
Notes
I have tried to remove the callback URL from the parameters as well and that didn't work. I have tried all sort of slightly different permutations (urlencoded my signature, added the callback URL in the query string, removed it etc), but I have lost track at this point the one's I have tried and haven't (encodings, quotes etc.).
Ignore the fact that I am not serializing the response into a model yet as the goal is to first hit a success status code!
I have an integration test setup for this method as well and I keep getting 400 Bad Request with no additional information (which makes sense), but is absolutely not helping with debugging.
[Fact]
public async Task TwitterHttpClientTests_GetOAuthRequestToken_GetsToken()
{
var result = await twitterHttpClient.GetUserOAuthRequestToken();
Assert.NotNull(result);
}
As an aside I had some other questions as well:
Is there a way to verify a user's Twitter account without going
through the OAuth flow? The reason I ask this is because getting
through OAuth flow is proving to be difficult
Is it safe to do the first step of the Twitter login workflow on the back end and return the response to the front end? The response
would carry a sensitive token and token secret. (If I were to answer
this myself I would say you have to do it this way otherwise you
would have to hard code app secrets into front end configuration
which is worse). I ask this because this has been on my conscious
since I have started this and I'm worried a bit.
Is there an OAuth helper library for C# ASP.NET Core that can make this easier?
I solved this by writing unit tests and working through the Twitter documentation on Creating A Signature. Since that example provides keys and results, it's possible to verify that your code is correct.
Since you asked about libraries - I wrote LINQ to Twitter with the hope of helping others like myself with this difficult task.
In addition to to signature, the page navigation can be challenging as your code works through the OAuth flow. Please review the Twitter documentation on Obtaining user access tokens to understand this better. I've also documented this in the LINQ to Twitter Wiki on Securing your Applications. Here's how this will work with LINQ to Twitter:
First, I have an OAuthController with a Begin action to redirect a user to for kicking off the authentication process:
public async Task<ActionResult> Begin()
{
//var auth = new MvcSignInAuthorizer
var auth = new MvcAuthorizer
{
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
{
ConsumerKey = configuration["Twitter:ConsumerKey"],
ConsumerSecret = configuration["Twitter:ConsumerSecret"]
}
};
string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");
return await auth.BeginAuthorizationAsync(new Uri(twitterCallbackUrl));
}
Notice that it's using an MvcSignInAuthorizer, passing in credentials via the CredentialStore property. If you were using your own raw code, you would be setting up the HTTP request with the Authorization header.
Next, notice that I'm modifying the current URL so that it will reference the same controller, but with the Complete endpoint. That is the oauth_callback that gets sent to Twitter authorization.
That process redirects the user to the Twitter web site, they authorize your app, and then it uses the oauth_callback to redirect the user back to your site. Here's how you handle that:
public async Task<ActionResult> Complete()
{
var auth = new MvcAuthorizer
{
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
};
await auth.CompleteAuthorizeAsync(new Uri(Request.GetDisplayUrl()));
// This is how you access credentials after authorization.
// The oauthToken and oauthTokenSecret do not expire.
// You can use the userID to associate the credentials with the user.
// You can save credentials any way you want - database,
// isolated storage, etc. - it's up to you.
// You can retrieve and load all 4 credentials on subsequent
// queries to avoid the need to re-authorize.
// When you've loaded all 4 credentials, LINQ to Twitter will let
// you make queries without re-authorizing.
//
//var credentials = auth.CredentialStore;
//string oauthToken = credentials.OAuthToken;
//string oauthTokenSecret = credentials.OAuthTokenSecret;
//string screenName = credentials.ScreenName;
//ulong userID = credentials.UserID;
//
return RedirectToAction("Index", "Home");
}
Again, you can see that I'm using MvcAuthorizer and completing the request. After completing the request, you'll be able to pull out the oauth_token and oauth_token_secret, as well as screen_name and user_id. You can save these artifacts and re-use them for all subsequent activity by this user, making their experience better because they don't have to log in every time you need to make a request.
On your question about verification, there is a Verify Credentials endpoint.
LINQ to Twitter has an ASP.NET Core Sample, API Samples with 100% API coverate, and full documentation on the Wiki if you want to learn more.
After hours and hours of going through the documentation I found the answer out. Turns out I missed some small details from the guides.
When making a request to oauth/request_token, when you sign the
request, you don't use the access token secret (for this specific request). Also, see the "Getting Signing Key" section of the signing a request guide and read the last few paragraphs. Therefore the signing key
does not have the access token secret
You must UrlEncode every single key and value. You must UrlEncode the authorization header as well.
I will post the updated code for you all here in case you need this in C#. Note that this code is not clean. You should separate OAuth functionality into some other class. This was my attempt to just get it to work.
public async Task<string> GetUserOAuthRequestToken()
{
int timestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
string nonce = Convert.ToBase64String(Encoding.ASCII.GetBytes(timestamp.ToString()));
string consumerKey = twitterConfiguration.ConsumerKey;
string oAuthCallback = twitterConfiguration.OAuthCallback;
string requestString =
twitterConfiguration.EndpointUrl +
OAuthRequestTokenRoute;
string parameterString =
$"oauth_callback={WebUtility.UrlEncode(twitterConfiguration.OAuthCallback)}&" +
$"oauth_consumer_key={WebUtility.UrlEncode(twitterConfiguration.ConsumerKey)}&" +
$"oauth_nonce={WebUtility.UrlEncode(nonce)}&" +
$"oauth_signature_method={WebUtility.UrlEncode(OAuthSigningAlgorithm)}&" +
$"oauth_timestamp={WebUtility.UrlEncode(timestamp.ToString())}&" +
$"oauth_version={WebUtility.UrlEncode("1.0")}";
string signatureBaseString =
"POST&" +
WebUtility.UrlEncode(requestString) +
"&" +
WebUtility.UrlEncode(parameterString);
string signingKey =
WebUtility.UrlEncode(twitterConfiguration.ConsumerSecret) +
"&";
byte[] signatureBaseStringBytes = Encoding.ASCII.GetBytes(signatureBaseString);
byte[] signingKeyBytes = Encoding.ASCII.GetBytes(signingKey);
HMACSHA1 hmacSha1 = new HMACSHA1(signingKeyBytes);
byte[] signature = hmacSha1.ComputeHash(signatureBaseStringBytes);
string base64Signature = Convert.ToBase64String(signature);
string authenticationHeaderValue =
$"oauth_nonce=\"{WebUtility.UrlEncode(nonce)}\", " +
$"oauth_callback=\"{WebUtility.UrlEncode(twitterConfiguration.OAuthCallback)}\", " +
$"oauth_signature_method=\"{WebUtility.UrlEncode(OAuthSigningAlgorithm)}\", " +
$"oauth_timestamp=\"{WebUtility.UrlEncode(timestamp.ToString())}\", " +
$"oauth_consumer_key=\"{WebUtility.UrlEncode(twitterConfiguration.ConsumerKey)}\", " +
$"oauth_signature=\"{WebUtility.UrlEncode(base64Signature)}\", " +
$"oauth_version=\"{WebUtility.UrlEncode("1.0")}\"";
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(
baseUri: new Uri(twitterConfiguration.EndpointUrl),
relativeUri: OAuthRequestTokenRoute);
request.Headers.Authorization = new AuthenticationHeaderValue("OAuth",
authenticationHeaderValue);
HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request);
if (httpResponseMessage.IsSuccessStatusCode)
{
string response = await httpResponseMessage.Content.ReadAsStringAsync();
return response;
}
else
{
return null;
}
}

Make API call with Basic Auth using App Pool Credentials

I am wondering if in .NET, if it possible to send over the credentials of the identity running an application pool in IIS to an API that uses Basic Auth. I have successfully been able to retrieve the identity context from the application pool. However, in every example i see for using Basic Auth. They all seem to require to manually add the Authorization header to the request. This is a problem since i do not directly have access to the password of the windows identity thus i can't manually create the Basic Auth Token. I have been trying to use the .DefaultCredentials property but it fails to generate the Auth header thus the response fails with 401. If this isn't possible then i'll take a different approach but wanted to make sure before i do so. The full code sample is below...i have tried multiple ways but all end up with the same 401.
using (var impersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero))
{
HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("url");
HttpClient request2 = new HttpClient();
WebClient request3 = new WebClient();
WebRequest request4 = WebRequest.Create("url");
try
{
// this code is now using the application pool indentity
try
{
//Method 1
//request1.UseDefaultCredentials = true;
//request1.PreAuthenticate = true;
//string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(WindowsIdentity.GetCurrent().Name + ":" + "No password :("));
//request1.Headers.Add("Authorization", "Basic " + WindowsIdentity.GetCurrent().Token.ToString());
//HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
//using (var reader = new StreamReader(response.GetResponseStream()))
//{
// JavaScriptSerializer js = new JavaScriptSerializer();
// var objText = reader.ReadToEnd();
// Debug.WriteLine(objText.ToString());
//}
////Method 2
//client.DefaultRequestHeaders.Accept.Clear();
//client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", WindowsIdentity.GetCurrent().Token.ToString());
//HttpResponseMessage response2 = client.GetAsync("url").Result; //.Result forces sync instead of async.
//var result = response2.Content.ReadAsStringAsync().Result;
//Debug.WriteLine(result);
//Method 3
//client2.Credentials = CredentialCache.DefaultNetworkCredentials;
//var result2 = client2.DownloadString("url");
//Debug.WriteLine(result2);
//Method 4
//request4.Credentials = CredentialCache.DefaultCredentials;
//string result4;
//using (var sr = new StreamReader(request4.GetResponse().GetResponseStream()))
//{
// result4 = sr.ReadToEnd();
//}
//Debug.WriteLine(result4);
}
catch (Exception ex)
{
throw new Exception("API Call Failed: " + ex.ToString() + " for " + WindowsIdentity.GetCurrent().Name + " request: " + request4.Headers.ToString());
}
}
finally
{
if (impersonationContext != null)
{
impersonationContext.Undo();
}
}
App Pool Identity and Basic Auth serves two different purpose and I suggest not to mix those. As you also mentioned that you don't know the password of app pool identity and it's self explanatory. App pool identity also allows the API's to access system resources for example, accessing a file share.
Whereas Basic Auth allows you to secure your API as a whole from being wide open and anyone accessing it. Except the ones who knows UserName:Password which needs to be passed with each HttpRequest (containing HttpHeader with UserName:Password in Base64).
Considering these facts, when API developer needs to share UserName and Password with all the parties, it's advisable not to share App Pool Identity credentials.
I have worked with both App Pool Identity and Basic Auth and I recommend to keep these separate.

Why do I keep getting 403 User does not have sufficient permission for this profile error from Analytics API

EDIT: Also I have read the following posts on Stack Overflow, but I don't think they have the solution I am looking for:
Google Analytics throws 403 error
Google Analytics API: "User does not have sufficient permissions for this account."
I am creating an installed application in C# to access and display my Google Analytics Data.
I have read Google's documentation for OAuth v2.0 and the Analytics v3 API, and I cannot retrieve my analytics data. Here is what I have done so far.
Navigate to the following URL in a Web Browser where I am prompted to log in to my Google Account (the account that owns the Analytics Account and has full ownership and permission) or if my browser has saved my login, an accept screen comes up asking me to confirm that I want to allow the app to access my analytics data. Here is the URL:
https://accounts.google.com/o/oauth2/auth?redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&client_id=XXXXXX.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics.readonly&approval_prompt=force&access_type=offline");
After the code is successfully returned and retrieved from the browser title window as the OAuth 2.0 documentation specifies for installed applications, I take this code and Create the following request which successfully returns an access token:
WebRequest request = WebRequest.Create("https://accounts.google.com/o/oauth2/token");
string body = String.Format("code={0}&client_id=XXXXXXXXXXX.apps.googleusercontent.com&client_secret=XXXXXXXXXXX&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code"
,browser.OAuthCode);
request.Method = "POST";
byte[] reqBytes = Encoding.UTF8.GetBytes(body);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = reqBytes.Length;
request.GetRequestStream();
Stream stream = request.GetRequestStream();
stream.Write(reqBytes, 0, (int)request.ContentLength);
WebResponse response = request.GetResponse();
Stream s = response.GetResponseStream();
StreamReader sr = new StreamReader(s);
string json = sr.ReadToEnd();
OAuthResponse tokenHolder = new OAuthResponse();
tokenHolder = Newtonsoft.Json.JsonConvert.DeserializeObject<OAuthResponse>(json);
return tokenHolder.AccessToken;
Finally, after successfully retrieving an access token, I create another Request to retrieve my analytics data like so:
public WebRequest ApiRequest()
{
string oAuthToken = OAuthToken();
//need to change this so people can select different ones
string idParam = "ids=ga:XXXXXX";
startDate = "start-date=" + startDate;
endDate = "end-date=" + endDate;
string totalEventsMetric = "ga:totalEvents";
string uniqueEventsMetric = "ga:uniqueEvents";
string categoryDimension = "ga:eventCategory";
string actionDimension = "ga:eventAction";
string labelDimension = "ga:eventLabel";
string parameters = "";
if ((bool)this._showTotalEvents.IsChecked)
parameters += "metrics=" + totalEventsMetric;
if ((bool)this._shwoUniqueEvents.IsChecked)
if (parameters != "")
parameters += "," + uniqueEventsMetric;
else
parameters += "metrics=" + uniqueEventsMetric;
if ((bool)this._showCategory.IsChecked)
if (parameters != "")
parameters += "&dimensions=" + categoryDimension;
else
parameters += "dimensions=" + categoryDimension;
if ((bool)this._showAction.IsChecked)
if (parameters != "" & parameters.Contains("dimensions"))
parameters += "," + actionDimension;
else if (parameters != "" & !parameters.Contains("dimensions"))
parameters += "&dimensions=" + actionDimension;
else
parameters += "dimensions=" + actionDimension;
if ((bool)this._showLabel.IsChecked)
if (parameters != "" & parameters.Contains("dimensions"))
parameters += "," + labelDimension;
else if (parameters != "" & !parameters.Contains("dimensions"))
parameters += "&dimensions=" + labelDimension;
else
parameters += "dimensions=" + labelDimension;
if (parameters != "")
{
parameters += "&" + idParam;
parameters += "&" + startDate;
parameters += "&" + endDate;
}
else
{
parameters += idParam;
parameters += "&" + startDate;
parameters += "&" + endDate;
parameters += "&metrics=" + totalEventsMetric;
parameters += "," + uniqueEventsMetric;
}
string url = string.Format("https://www.googleapis.com/analytics/v3/data/ga?{0}", parameters);
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
request.Headers.Add("Authorization: Bearer " + oAuthToken);
return request;
}
My url ends up looking something like this:
https://www.googleapis.com/analytics/v3/data/ga?metrics=ga:totalEvents,ga:uniqueEvents&dimensions=ga:eventCategory,ga:eventAction,ga:eventLabel&ids=ga:XXXXX&start-date=2013-12-01&end-date=2014-01-01
And my Header:
{Authorization: Bearer oAuthTokenGoesHere}
And the error I get every time:
{"error":{"errors":[{"domain":"global","reason":"insufficientPermissions","message":"User does not have sufficient permissions for this profile."}],"code":403,"message":"User does not have sufficient permissions for this profile."}}
I cannot figure out why I am getting this error when this is an installed program. I log into the actual account in the web browser that opens up before I click accept and retrieve the OAuth code to exchange for a token. I have tried adding the App Engine and Compute Engine email address form the developer's console to my analytics account using the web interface, but this does not help. There is no email address associated with client ids for installed applications either, presumably because you have to log in in a browser before you can get a code.
I also tried passing the token in as a parameter instead of a header, but that did not work either.
I am not sure what to do from here.
I was providing the wrong id number to access my Analytics data. I was using the id contained in the table id (I am pretty sure this is what it is called) that looks like UA-XXXXXX-1 when this is the account id number. Eventually after going back and rereading all of the documentation I saw where it said to use the profile (view) Id.
Actually this post:
Google Analytics throws 403 error
mentioned that you need to make sure you are using the correct id, but the reason I did not think this referred to me was because it called the number the profile id, but when I was looking in Google Analytics, I could not find a profile id. In the analytics web interface, it is called the view id. I must have gotten lost in the sea of documentation and forgot about this part:
https://developers.google.com/analytics/devguides/reporting/core/v3/reference#ids
where it specifically says to use the "view (profile) id".
This is a simple error. You are trying to access a profile for which your Google Account has no authorisation. Kindly log in to the GA account, and navigate to the View/Profile you're trying to access, and go to Admin -> View -> User Management -> Add Permissions For:. This is the error which occurs only when you try to access a profile for which you don't have authorisation.
Also remember, sometimes you might have a few Google Accounts, only one of which has access to the Analytics profile in question (for example, home and work accounts). Sometimes when you're already logged in to a Google Account which does not have access to the Analytics profile in question, but you have logged in for the OAuth process using that account (which has no access) and given the C# application the authority to use those credentials, it will not ask you to log in. Say you're logged in to your home account which doesn't have access, and you use your C# application. During the OAuth authentication process, all it asks for now is whether you authorise this application to use your Google Account credentials. If you don't sign out of your home account and re-sign-in with your work account before this OAuth Authentication, then this error will occur infinitely, since your Account really does not have access to the profile in question at all.

Aweber C# Api unauthorized - AccessToken key is invalid

I am having an issue with the Aweber C# api from: http://aweber.codeplex.com/
I am getting an unauthorized response from the following code. I was wondering if someone could help me see what I am missing please?
String consumerKey = "####";
String consumerSecret = "####";
API api = new API(consumerKey, consumerSecret);
api.OAuthToken = "####";
api.OAuthTokenSecret = "####";
api.OAuthVerifier = "##";
Aweber.Entity.Account account = api.getAccount();
I am assuming I am missing something important, but I cant figure out what is is.
Thanks in advance for your help.
D.
You need to add following code before api.getAccount();
// Set callback url (if not set will default to this page)
api.CallbackUrl = "http://" + Request.Url.Host + ":" + Request.Url.Port + "/Authorize.aspx";
// Get request token
api.get_request_token();
// Save the token and secret in session
HttpContext.Current.Session.Add("oauth_token", api.OAuthToken);
HttpContext.Current.Session.Add("oauth_token_secret", api.OAuthTokenSecret);
// Will redirect user to the Aweber authorize page
api.authorize();

Categories