I would like to utilize the following API from Google: https://cloud.google.com/functions/docs/reference/rest/
I make a GET /v1/{name}/locations request to the endpoint and receive an HTTP 401 Error. This means I have not set up authentication.
For reference, here is the code I am running:
import requests
def list(project_id):
endpoint = 'https://cloudfunctions.googleapis.com/v1/projects/'
endpoint += project_id
endpoint += '/locations'
r = requests.get(endpoint)
return r
The documentation linked states that I am required to have one of the two following OAuth scopes:
https://www.googleapis.com/auth/cloudfunctions
https://www.googleapis.com/auth/cloud-platform
How do I acquire these scopes? I have already downloaded a credentials file and exported an environment variable as listed in the documentation here. I am currently not using these credentials anywhere, since it seems like a security risk to send a private key over plain text.
Could someone please explain how to turn this 401 Authentication Error into a 200 Success (or any other error)?
Related
As there is no available feature in MS Graph API to have access to MS Form responses (LINK), what's the code solution to have access to shared online MS Form responses?
I know the following available approaches:
Manually download the responses by clicking on Responses -> Open in Excel and then upload it to the target location (It's a completely manual process and could not be automated by a code script which is not desired at all in my case)
Share with a group first which gives me the option to have online access to the response file by clicking on Responses -> Open in Excel. This time it automatically creates an excel file in the group's OneDrive instead of downloading the file. Now I could read the excel file via MS Graph API. (This solution works but I need to share the Form with a group first and then manually click Responses -> Open in Excel to create the excel file)
Any thought that assists to have a complete code solution is appreciated
I would stick with the above approaches which you said above. In addition, you can consider using Microsoft Flow or Power automate to perform the above to automate the above approach. AFAIK i failed to see any Graph API exposed on this so far. Being said that i would suggest you can consider filing Microsoft Uservoice - so that they can consider implementing it. You upvoted the the uservoice as well.
I came up with this for what I needed recently. The documentation seems to be deliberately vague, so this may not work in the future. I used unofficial and official info from various sources on stackoverflow and MS documentation. There is an (undocumented) API to pull the responses but it requires an access token. In python you can use Microsoft's azure-identity package to get the token, then use it to request the form responses. Here's the outline:
the scope of authorization for an access token for MS Forms is: https://forms.office.com/.default
the endpoint for fetching the responses is: https://forms.office.com/formapi/api/{tenantid}/users/{userid}/light/forms('{formid}')/responses
where {tenantid} is the Azure Tenant ID, {userid} is the Azure user's Object ID, and {formid} is the id of the form (i.e. the id query parameter at the end of the form's URL). This URL requires an access token that entitles the requester to get the data.
use one of the Credential object types in azure.identity package and call its get_token(scope) method with the scope specified above to receive the token. Depending on which type you choose, you may need to login to Azure using az login, or a browser login, or use the current logged-in user's credentials.
Use the returned token as the Bearer token to authorize access to response endpoint (item 2 above)
Like this:
import os
import requests
from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential, AzureCliCredential
# Use one of these credential objects to get an access token
cred = AzureCliCredential() # i.e. `az login`
# cred = InteractiveBrowserCredential()
# cred = DefaultAzureCredential()
# Request an access token with the following scope
scope = "https://forms.office.com/.default"
tok = cred.get_token(scope)
# print(tok)
# print(type(tok))
formid = os.getenv("FORMS_FORM_ID")
tenantid = os.getenv("FORMS_TENANT_ID")
userid = os.getenv("FORMS_ADMIN_ID")
url = f"https://forms.office.com/formapi/api/{tenantid}/users/{userid}/light/forms('{formid}')/responses?$expand=comments&$top=7&$skip=0"
# print(url)
# Provide the access token in the request header
headers = {"Authorization": f"Bearer {tok.token}"}
r = requests.get(url, headers=headers)
print(r.json())
On Postman, I can get new access token for OAuth2.0 by providing callback URL, auth URL and client ID.
I want to break this task down on JMeter because I cannot find this function there. From my understanding, it is divided into authenticate -> authorise -> call back.
Authenticate
URL = https://xxxxx/login
Result = Authorising URL
Authorise
URL = https://xxxxx/oauth/authorize?client_id=mmm&redirect_uri=https://yyyyy/auth/callback&response_type=code
Result = code (e.g. zzz)
Call back
URL = https://yyyyy/auth/callback?code=zzz
Result = token
As I used HTTP(S) Test Script Recorder on JMeter, I got the three actions mentioned above. When I reran them, it told me this error on Authenticate part: <oauth><error_description>Full authentication is required to access this resource</error_description><error>unauthorized</error></oauth>.
To make sure that it was not about the program I use, I did it on Postman and found this error as well.
I wonder how I can break OAuth2.0 Get New Access Token feature into basic API settings in order to get access token on Postman or JMeter.
Dont' compare these tools:
Postman is an Electron application, it's basically a heavily customised Chromium web browser + NodeJS
According to JMeter main page
JMeter is not a browser, it works at protocol level. As far as web-services and remote services are concerned, JMeter looks like a browser (or rather, multiple browsers); however JMeter does not perform all the actions supported by browsers. In particular, JMeter does not execute the Javascript found in HTML pages. Nor does it render the HTML pages as a browser does (it's possible to view the response as HTML etc., but the timings are not included in any samples, and only one sample in one thread is ever displayed at a time).
If you can obtain the token using Postman you can just add HTTP Header Manager to your JMeter Test plan and configure it to send Authorization header with the value of Bearer YOUR_TOKEN_FROM_POSTMAN and JMeter should let you in.
After testing, I found that Postman's OAuth 2.0 Get New Access Token popped up a login page of targeted URL where I needed to fill in the username and the password so that the token could be obtained.
As I tried breaking down APIs required for this login, it required GET of that https://yyyyy and POST of that https://xxxxx/login. Click Send for POST, with username and password contained in form-data, then click Send for GET. The GET response would contain such the token.
However, just putting the aforementioned GET and POST APIs into one thread group did not work on JMeter. As I used HTTP(S) Test Script Recorder to no avail, I went with BlazeMeter and realised that it was using Transaction Controller containing 1) GET of https://yyyyy 2) POST of https://xxxxx/login. With these two arranged top-down, the job would be successful. The token was contained in the response of 2).
For now, this has been my discovery which answers my question.
Try BlazeMeter.
I am trying to do a request my Netsuite RESTlet using Alamofire (SWIFT) but I meet several difficulties:
In the documentation it's specify the different parameters needed (see below).
DOCUMENTATION:
An OAuth 1.0 RESTlet authorization header requires the data described in the following table. Some of these values can be obtained from the NetSuite UI. Other values must be calculated. Typically, your integration should include logic to identify these values and generate the finished header. Follow the OAuth 1.0 protocol to create the authorization header.
However in postman I am using extra parameters (consumer Secret and the Token Secret) and it's works if I remove them it doesn't works
To finish when i check the Authorization header generated by postman, I see only the specify parameters in the documentation :
OAuth realm="my realm",oauth_consumer_key="myConsumerKey",oauth_token="myAccessToken",
oauth_signature_method="HMAC-SHA1",oauth_timestamp="1543488570",
oauth_nonce="ERxdLbUfkeh",oauth_version="1.0",oauth_signature="UeqmxAyeUqtPoICLo%2FARsQE8B1E%3D"
If someone can explain me this, I could implement TBA authentification in my Application but for now I need to understand better this authentification.
I also spend a few hours trying to make it work. In my case I wasn't adding the account ID to the realm param. Here a picture of what I ended with:
Here where you can get the account ID:
I hope it helps
The explanation of why the consumer secret and the token secret are needed by Postman to generate the token is shown in SuiteAnswer 42019 - as referenced in the Notes section beside oauth_signature in your screenshot above. From that page:
Sign the result string from step 5 using the consumer secret and token secret concatenated using '&' (For this case, HMAC-SHA1 or HMAC-256).
In other words, Postman uses the secrets to generate the output which authenticates your credentials - you cannot generate the oauth_signature correctly without them.
I ran into a lot of issues with NetSuite broken RESTlet/TBA connections as well. I did build this out in our software to help out customers. You can see the methods I used in the article below.
Using NetSuite TBA by Calling a RESTlet from an HTTP Source or Target
I'm a newbie to this stuff so downloaded the samples which is all fine and I thought I could see what was going on and what I needed to do. However, got a bit stuck for no obvious reason so I wondered if anyone could maybe give me some hints.
I'm trying to engineer Cognito authentication and identity into an old Apache Struts 1 legacy web application written in Java, so all the activity needs to be server-side. Using the Cognito https://xxx.auth.xxx.amazoncognito.com/login? URL I can successfully authenticate and get an auth code back using this URL providing my client id, redirect URI and response_type=code so all good thus far.
If I then create an HttpClient (as per the sample code in Github) and call the token URL https://xxx.auth.xxx.amazoncognito.com/oauth2/token and write various parameters to the request body (grant_type=authorization_code, client_id=as previously, redirect_uri=my URI and code=auth code just returned), I get an "unauthorized_client" message returned. But the code is valid albeit for authorization, and the client_id is correct because I used it previously.
My log:
Cognito following successful signin, continuing to url http:[redacted]/passport/CognitoHandlerSignIn.do?code=62eeb0b1-a76b-489b-bd28-e42023a497bd
(this was the /login succeeding)
Callback from Cognito received
(following is the log dump of the /oauth2/token URI called to)
Cognito token signin URL is https:[redacted].amazoncognito.com/oauth2/token
HTTP request header, added Authorization=Basic M29wcGR0azdpYzF2YjloNGd0OTQzNXYxcmI6MW9mMmFsaWNzZGR2dHZ1NmFkOHRuc2s4cnJ0cXEyYm0yc3RqbG1mcmkyamhkdXBubG1wMw==
HTTP request header, added Content-Type=application/x-www-form-urlencoded
HTTP request body, added grant_type=authorization_code
HTTP request body, added
redirect_uri=https%3A%2F%2F<redacted>%2Fpassport%2FCognitoHandlerSignIn.do
HTTP request body, added code=62eeb0b1-a76b-489b-bd28-e42023a497bd
HTTP request body, added client_id=[redacted]
HTTP request is sun.net.www.protocol.https.DelegateHttpsURLConnection:https:
[redacted].auth.eu-west-1.amazoncognito.com/oauth2/token
HTTP Json result=<{"error":"unauthorized_client"}>
org.json.JSONException: JSONObject not found.
at org.json.JSONObject.get(JSONObject.java:454)
at
What's wrong with this picture? I tried also adding client_id, code as URL parameters but I just get an "invalid_client" message instead.
I also tried using the /oauth2/token URI directly from the Struts app to provide a token but it returns the id_token using # rather than ? in the parameter list so it is client-side only and hence can't be intercepted by the Struts app and so will be a pain to forward to the server, but I could write some Javascript to do it if I had to. It doesn't seem the path of least resistance, though, as it seems wrong that the pure Java server side call doesn't work so I must be doing something wrong which isn't obvious to me.
On this page, https://github.com/doorkeeper-gem/doorkeeper/wiki/Supported-Features, it mentions support for Implicit Grants. It looks like the authorizations#create is the endpoint I want and it does return an access_token but it doesn't return the other parameters that are required.
Request
https://localhost/oauth/authorize?client_id=<client_id>&response_type=token&redirect_uri=urn:ietf:wg:oauth:2.0:oob
I get redirected to:
Redirect
https://localhost?access_token=<access_token> with the body:
{"resource_owner_id":<user_id>,"scopes":[],"expires_in_seconds":7776000,"application":{"uid":"<client_id>"},"created_at":1484857630}
What I need per the spec, is a redirect with query parameters:
https://localhost#access_token=<access_token>&token_type=bearer&expires_in=<seconds>&scope=<scope>
Is the use of the testing redirect value of "redirect_uri=urn:ietf:wg:oauth:2.0:oob" changing the response?
Also notice the ? instead of the # just before the response query parameters. I'm not sure what the spec says on that but Amazon OAuth2 clients require the # sign.
How do I get the token_type=bearer be included?
Thanks.
I was able to get my service working by looking at the code. So the answers to my questions above are:
urn:ietf:wg:oauth:2.0: is called the native URI. There is branching in the code which alters the response when it's set to the native URI. Using ngrok to create an externally callable endpoint on my local machine, I used a true redirect_uri value and Doorkeeper responded with the correct parameters in the response (including the token_type=bearer and # sign).
Note: It worked from my Amazon Alexa skill only after modifying the Doorkeeper code to allow redirect URLs that contain query parameters. Amazon's redirect URLs are in the format https://pitangui.amazon.com/spa/skill/account-linking-status.html?vendorId=<vendorId> which is currently not supported by Doorkeeper and an error is thrown about an Invalid Redirect URI.