I am in the process of learning the Autodesk Forge API. With a simple C# application, I am able to authenticate using the Forge API.
var responseString = await
"https://developer.api.autodesk.com/authentication/v1/authenticate"
.PostUrlEncodedAsync(new
{
client_id = Client_ID.Text,
client_secret = Client_Secret.Text,
grant_type = "client_credentials",
scope = "data:read data:write bucket:create bucket:read"
})
.ReceiveJson();
Though I have explicitly specified the bucket:read scope bucket:read, further call to check a bucket exists fails with error:-
Http code 403 (Forbidden) with the message "Only the bucket creator is allowed to access this API"
When I try to create another bucket with the same name it fails with the:-
Http Code 409 (Conflict) with the message "Bucket already exists"
Can someone please help me on what is missing here?
Yes, the issue is that your bucket key should be globally unique across all application and regions. You can check the doc at https://developer.autodesk.com/en/docs/data/v2/reference/http/buckets-POST/ for the detail, especially for the description of Bucket Key.
Related
I want to use the V3 SnipCart API to get data about specific orders on my thank you page. I am using C# to do this. I keep getting this error when trying to use the API
System.Net.WebException:'The remote server returned an error: (401)
Unauthorized.'
I have tried to follow their documentation by using only the API key with no password as shown here. Below is my code that I wrote that is giving me the error. I wrote this inside my controller. I get the error as soon as the breakpoint hits this line responseObjGet = (HttpWebResponse)requestObjGet.GetResponse();
//Testing API get data begin
string strurltest = String.Format("https://app.snipcart.com/api/orders/c5541254-r8541-8501-0024-juy85vv002154");
WebRequest requestObjGet = WebRequest.Create(strurltest);
requestObjGet.Credentials = new NetworkCredential("HihiukoJOUBVCTYIiijiGiiYTd6tOiUyTYo", "");
requestObjGet.Method = "GET";
HttpWebResponse responseObjGet = null;
responseObjGet = (HttpWebResponse)requestObjGet.GetResponse(); //401 is triggered here
string strresulttest = null;
using (Stream stream = responseObjGet.GetResponseStream())
{
StreamReader sr = new StreamReader(stream);
strresulttest = sr.ReadToEnd();
sr.Close();
}
Concerns that I have as well are the following:
1.The API key that I entered here is my public api key since I am still in the development and testing phase. I am not sure if this api call will work with the test api key or if I have to use the real secret production key. Any thoughts?
2.I am debugging this off my local machine (localhost:) for now before I deploy these API calls to production to test these changes in prod still with the test api key, could that be a reason for the 401? Since the URL that is trying to get the info is my localhost: url and not my actual domain that I added to SnipCart Dashboard. I was thinking maybe I have to try and hit this from prod environment instead? Any thought?
These are the 2 possibilities that come to mind for me. I am not too savvy on APi's yet so I don't know if my call is missing something.
Summary: All I am trying to do is be able to use the API so that I can load the data I want for an order when users reach my custom thank you page with their token.
Our 401 "Unauthorized" status code is returned when the authentication failed to our API with your Authorization header's value.
Here's the documentation about the auth to our APIs. Make sure to return us a base64 value of your secret API key and the trailing single colon character at the end to respect the Basic Authentication Scheme.
And if you are trying to get data for an order that was placed in live mode then you would need to use the live secret API key.
I have a sendgrid account which includes 7 days of email history.
I try to get these with the api command:
var sendgridtask = sendgridclient.RequestAsync(method: SendGrid.SendGridClient.Method.GET, urlPath: "messages?limit=10");
but this gives the response:
{"errors":[{"message":"authorization required"}]}
I guess the api key isn't correct, but when I try to execute the command:
var sendgridtask = sendgridclient.RequestAsync(method: SendGrid.SendGridClient.Method.GET, urlPath: "suppression/bounces/" + email);
it gives no error and responses the right info.
I checked the api key and it has full access.
I've also tried:
sendgridclient.AddAuthorization(new KeyValuePair<string, string>("Authorization", $"Bearer {apiKey}"));
but this gives the same response
Do you know what I am doing wrong?
Already got an answer from SendGrid:
Unfortunately in order to gain access to the Email Activity Feed API, you must purchase additional email activity history.
Or you can use our event webhook for your activity. https://sendgrid.com/docs/for-developers/tracking-events/getting-started-event-webhook/
So it seems that our license included history is only accessible from the SendGrid website, not from the API without an additional license.
I'm trying to use the Google Admin Settings API with a Service Account with no success from a C# Console application.
From what I've understood, I first have to get an OAuth token. I've tried 2 methods successfully for this: using Google.Apis.Auth.OAuth2.ServiceAccountCredentials or by creating manually the JWT assertion.
But when I call an Admin Settings API with the OAuth token (maximumNumberOfUsers for instance), I always get a 403 error with " You are not authorized to perform operations on the domain xxx" message.
I downloaded GAM as the author calls this API too so that I can compose the same HTTP requests. Like explained in GAM wiki, I followed all the steps to create a new Service Account and a new OAuth Client ID so that I can be sure it's not a scope issue. I also activated the debug mode like proposed by Jay Lee in this thread. Like explained in the thread comments, it still doesn't work with my OAuth token but the call to the API succeeds with GAM OAuth token.
So it seems it's related to the OAuth token itself. An issue I get while creating the OAuth token is that I can't specify the "sub" property (or User for ServiceAccountCredentials). If I add it, I get a 403 Forbidden response with "Requested client not authorized." as error_description while generating the token i.e. before calling the API. So maybe it is the issue but I don't see how to fix it as I use an Admin email.
Another possibility is that this API needs the OAuth Client credentials as GAM requires 2 different types of credentials, Service Account and OAuth Client. As I only can use Service Account credentials in my project, I'm afraid I will be stuck if it is the case...
I don't see other options and I'm stuck with both, so any help appreciated. Thanks!
My code:
public static string GetEnterpriseUsersCount()
{
string domain = MYDOMAIN;
string certPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
certPath = certPath.Substring(0, certPath.LastIndexOf("\\") + 1) + "GAMCreds.p12";
var certData = File.ReadAllBytes(certPath);
X509Certificate2 privateCertificate = new X509Certificate2(certData, "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL)
{
Scopes = new[] { "https://apps-apis.google.com/a/feeds/domain/" },
User = ADMIN_EMAIL
}.FromCertificate(privateCertificate));
Task<bool> oAuthRequest = credential.RequestAccessTokenAsync(new CancellationToken());
oAuthRequest.Wait();
string uri = string.Format("https://apps-apis.google.com/a/feeds/domain/2.0/{0}/general/maximumNumberOfUsers", domain);
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
if (request != null)
{
request.Method = "GET";
request.Headers.Add("Authorization", string.Format("Bearer {0}", credential.Token.AccessToken));
// Return the response
using (WebResponse response = request.GetResponse())
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
return sr.ReadToEnd();
}
}
}
return null;
}
Edit: I focused on scopes like advised by Jay Lee below and it appears that the missing scope was 'https://www.googleapis.com/auth/admin.directory.domain'. However, nowhere is this written in Admin Settings API documentation page. At least, I didn't find it. 'https://apps-apis.google.com/a/feeds/domain/' is necessary too but I already added it to the list of allowed scopes. Thanks Jay!
Edit 2: I also updated the source code so that it can help in the future.
You need to grant your service account's client ID access to the scopes for admins settings API. Follow the Drive domain wide delegation instructions except sub in the correct correct scope. Then you can set sub= without an error.
I wonder if it is possible to get a permanent access token for personal use on Reddit?
It will only be me using the App.
For users, the access token expires after 1 hour.
My using the below information that I have about my client-id and secret, I put up a start attempt of trying to get an access token. (MessageBox show "Error 401")
If a user will get a token, one have to click "Allow" in the browser. Very well described here. https://github.com/reddit/reddit/wiki/OAuth2
This it NOT what I am after. I am after for, personal use, an access token only through code. Is this possible?
String requestUrl = "https://ssl.reddit.com/api/v1/access_token";
RestSharp.RestClient rc = new RestSharp.RestClient();
RestSharp.RestRequest request = new RestSharp.RestRequest(requestUrl, RestSharp.Method.POST);
request.AddHeader("Content-Type", "application/json");
//request.AddHeader("Authorization", ""); //???
request.AddHeader("x-li-format", "json");
request.AddParameter("client_id", "abcdefg");
request.AddParameter("client_secret", "abc123-456");
request.AddParameter("grant_type", "abc123-456");
request.AddParameter("scope", "identity");
request.AddParameter("state", "adhasegw"); //whatever value
request.AddParameter("duration", "permanent");
request.AddParameter("redirect_uri", "http://mywebsite.co");
request.RequestFormat = RestSharp.DataFormat.Json;
RestSharp.RestResponse restResponse = (RestSharp.RestResponse)rc.Execute(request);
RestSharp.ResponseStatus responseStatus = restResponse.ResponseStatus;
MessageBox.Show(restResponse.Content.ToString() + "," + responseStatus.ToString());
As of right now, you cannot retrieve a permanent access token. You have 2 options that come close.
The first is to request a "refresh" token when using the standard OAuth flow. That's what you're doing by sending "duration" as "permanent" in your code. The refresh token can be used to automatically retrieve new 1 hour access tokens without user intervention; the only manual steps are on the initial retrieval of the refresh token.
The second alternative, which applies only when writing a script for personal use, is to use the password grant type. The steps are described in more detail on reddit's "OAuth Quick Start" wiki page, but I'll summarize here:
Create an OAuth client (under https://www.reddit.com/prefs/apps) with type = "script"
Make a request to https://www.reddit.com/api/v1/access_token with POST parameters grant_type=password&username=<USERNAME>&password=<PASSWORD>. Send your client ID and secret as HTTP basic authentication. <USERNAME> must be registered as a developer of the OAuth 2 client ID you send.
A client_id and client_secret can be generated for a reddit account by going to https://www.reddit.com/prefs/apps and creating an app:
The part I have hidden is my client_id.
Then you can use a client like praw to access reddit e.g. with Python:
import praw
r = praw.Reddit(client_id='insert id here',
client_secret='insert secret here',
user_agent='insert user agent')
page = r.subreddit('aww')
top_posts = page.hot(limit=None)
for post in top_posts:
print(post.title, post.ups)
You could use your current browser's user agent, which can be easily found by google searching "what is my user agent" (among other ways).
I'm have working two separate implementations of Oauth2 for both the gData and the Drive C# APIs, storing token information in an OAuth2Parameters and AuthorizationState respectively. I'm able to refresh the token and use them for the necessary API calls. I'm looking for a way to use this to get the user's information, mainly the email address or domain.
I tried following the demo for Retrieve OAuth 2.0 Credentials but I'm getting a compile error similar to rapsalands' issue here, saying it
can't convert from
'Google.Apis.Authentication.OAuth2.OAuth2Authenticator<
Google.Apis.Authentication.OAuth2.DotNetOpenAuth.NativeApplicationClient>'
to 'Google.Apis.Services.BaseClientService.Initializer'.
I just grabbed the most recent version of the Oauth2 api dlls so I don't think that's it.
All the other code samples I'm seeing around mention using the UserInfo API, but I can't find any kind of C#/dotnet api that I can use with it without simply doing straight GET/POST requests.
Is there a way to get this info using the tokens I already have with one of the C# apis without making a new HTTP request?
You need to use Oauth2Service to retrieve information about the user.
Oauth2Service userInfoService = new Oauth2Service(credentials);
Userinfo userInfo = userInfoService.Userinfo.Get().Fetch();
Oauth2Service is available on the following library: https://code.google.com/p/google-api-dotnet-client/wiki/APIs#Google_OAuth2_API
For #user990635's question above. Though the question is a little dated, the following may help someone. The code uses Google.Apis.Auth.OAuth2 version
var credentials =
await GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets {ClientId = clientID, ClientSecret = clientSecret},
new[] {"openid", "email"}, "user", CancellationToken.None);
if (credentials != null)
{
var oauthSerivce =
new Oauth2Service(new BaseClientService.Initializer {HttpClientInitializer = credentials});
UserInfo = await oauthSerivce.Userinfo.Get().ExecuteAsync();
}