Understanding AWS API Gateway with HTTP Proxy - aws-api-gateway

I am new in API gateways. I have python based API deployed on an EC2 server. I can access this as URL http://xxx.xxxxxxx.com/RPC2/. I can see objects, methods in this URL. I am trying to use API gateway for same.
Created API. (ExampleAPI)
Created POST method. (given path http://xxx.xxxxxxx.com/RPC2/ as end point URL ). I have not created the resource since I am expecting HTTP Proxy for all Methods of the resource. Its looks fine when I put my content in the request body. I get a response.
Now I have deployed it to one stage dev1. Got a new endpoint URL.
Also created an API key and attached it with dev1. Also Set API key required true in POST Method Request.
Questions.
1. When I hit dev1 URL (https://xxxxxxxxxxx-api.us-east-1.amazonaws.com/dev1), it does not give me same page as http://xxx.xxxxxxx.com/RPC2/. It gives me {"message":"Missing Authentication Token"} error. Am I missing some fundamentals here?
http://xxx.xxxxxxx.com/RPC2/ do have several methods, so how can I use it? All of them are POST methods. Can I set some parameters or some request body, or some templates? How can I improve this process?
How can I use API key here? Or it won`t work in POST method?
If i do curl -H "Content-Type: application/JSON" -X POST -d "{\"method\": \"app.menu\",\"params\":[] }" https://xxxxxxxxxxx-api.us-east-1.amazonaws.com/dev1 i get same response as i curl http://xxx.xxxxxxx.com/RPC2/. is it the only way to access my dev1 URL or I can create individual methods or string parameters.
Regards,
Ashish

See answers posted to this forum:
When i hit dev1 URL (https://xxxxxxxxxxx-api.us-east-1.amazonaws.com/dev1), it do not give
me same page as http://xxx.xxxxxxx.com/RPC2/. It gives me
{"message":"Missing Authentication Token"} error. Am i missing some
fundamentals here ?
If you are hitting the URL in a browser with a GET method, it will not
work. You have to specify all of the HTTP methods on a resource that
you want the client to access. If you hit a method that is not
defined, you get that message.
http://xxx.xxxxxxx.com/RPC2/ do have several methods, so how can i use it? all of them are POST methods. Can i set some parameters or
some request body, or some templates. how can i improve this process.
Yes if you are mapping to an RPC API then you can build the REST
methods/resources in API Gateway and set a static value for the header
or in the body, wherever the RPC action is expected by the backend.
How can i use API key here? or it won`t work in POST method? Because while accessing from curl, it works fine without API key.
First you should set API Key Required on the method (Method Request
page), then you'll have to add the API Stage to the API Key and make
sure it's enabled. After all that, if you send the API Key in a header
called 'x-api-key' it should work, otherwise you should get a 403
response saying "Forbidden".
If i do "curl -H "Content-Type: application/json" -X POST -d "{\"method\": \"app.menu\",\"params\":[] }"
https://xxxxxxxxxxx-api.us-east-1.amazonaws.com/dev1" i get same
response as i curl http://xxx.xxxxxxx.com/RPC2/. is it the only way to
access my dev1 URL or i can create individual methods or string
parametrs.
You will have to create each method in API Gateway (like GET) and they
can all point to the same backend url but specify a different RPC
action in the header or wherever it is specified.
I'd encourage you to check the public developer guides for parameter
mapping and payload transformation to learn what tools we have in API
Gateway.

Related

Why does Github actions rest API download artifacts by creating a temporary URL?

I am following the docs here https://docs.github.com/en/rest/actions/artifacts#download-an-artifact to use Github actions rest API to download artifacts. Given an ARTIFACT_ID and access token if the repo is private, one can call the API via cURL or the github CLI to get a response from github. The response header contains Location:... which provides a temporary URL lasting 1 minute from which the artifact can be downloaded. The artifact can then be downloaded via a second call to cURL.
I would like to know the reason for this design decision on the part of Github. In particular, why not just return the artifact in response to the first call to cURL? Additionally, given that the first call to cURL is intended to return a temporary URL from which the artifact can be retrieved, why not have this temporary URL returned directly by call to cURL rather than having it only contained in the header. Other information such as if the credentials are bad, or if the object has been moved are returned in json when this cURL command is run, so why can't the temporary URL also be contained here?
To help clarify my question, here is some relevant code:
# The initial cURL command looks something like this:
curl -v \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token <TOKEN>" \
https://api.github.com/repos/OWNER/REPO/actions/artifacts/ARTIFACT_ID/ARCHIVE_FORMAT
# the temporary URL, which can be curled to retrieve the artifact, looks like something like this:
curl https://pipelines/actions/githubusercontent.com/serviceHosts/<HEXSTRING>/_apis/pipelines/1/runs/16/\
signedartifactscontent?artifactName=<artName>&urlExpires=<date>&urlSigningMethod=HMACV2&urlSignature=<SIGNATURE>
Additionally, I am currently capturing the standard error of the cURL command and then running regex on it so as to extract the temporary URL. Is there a better way to do this? For example, is there a flag I could pass to cURL that would give me the value of Location directly?
Additionally, it is stated that The archive_format must be zip. Given this is the case, what is the benefit of having this parameter. Is it not redundant? If so, what is the benefit of this redundency?
This is a consequence of a 2011 design decision regarding https://github.blog/2011-08-02-nodeload2-downloads-reloaded/
When implementing a proxy of any kind, you have to deal with clients that can’t read content as fast as you can send it.
When an HTTP server response stream can’t send any more data to you, write() returns false.
Then, you can pause the proxied HTTP request stream, until the server response emits a drain event.
The drain event means it’s ready to send more data, and that you can now resume the proxied HTTP request stream.
TO avoid DDOS, it is better to manage that stream from a temporary URL, rather than a fixed one.
You can use -D to display response header, but you would still need to post-process its answer to get the redirection URL.

Configuring Keycloak through its REST API with cUrl

I need to configure Keycloak to get a JWT token as in this blog post, but I have to do it with cUrl. They create a client and then update it setting access type to confidential, Direct Grant Flow to direct grant, and Browser Flow to browser. The PUT request from the web UI that does this has some uuids that they seem to have pulled out of nowhere. Here is the relevant part of the payload:
"authenticationFlowBindingOverrides":{"browser":"6d77c4c7-15cf-4474-9b9f-7439dbc83b83","direct_grant":"5cb10cdb-9902-4f7f-b9da-68f887c49a75"}
The docs for the ClientRepresentation are no help. They show all fields are optional, which doesn't make sense, and the authenticationFlowBindingOverrides is a Map, but the link in their docs for the Map is dead.
Does anyone know where they get the uuids for browser and direct_grant from?
There is also nothing in the PUT payload that sets the Access Type to confidential.
If anyone has a cUrl implementation of the UI steps in the blog post that would be greatly appreciated.
The PUT request from the web UI that does this has some uuids that
they seem to pull out of nowhere.
Those uuids are generated by keycloak to get them you need to call the endpoint:
GET KEYCLOAK_HOST/auth/admin/realms/<YOUR_REALM>/authentication/flows
From the JSON response you need to parser it and get the field id of both the alias: "browser" and the alias: "direct grant".
After that call the endpoint:
PUT KEYCLOAK_HOST/auth/admin/realms/<YOUR_REALM>/clients/<YOUR_CLIENT_ID>
with the following payload:
'{"publicClient":false,"clientAuthenticatorType":"client-secret","authenticationFlowBindingOverrides":{"direct_grant":"<DIRECT_GRANT_ID>","browser":"<BROWSER_ID>"}}'
There is also nothing in the PUT payload that sets the Access Type to
confidential.
You need to set the field publicClient to false.

Postman collection Authorization not present in documentation headers

I have started using Postman to map out my API and also wanted have a quick, easy way to document it and share it.
My API is using JWT for auth and this token needs to be present in each request except login.
In order to keep it DRY I have used Postman collection Authorization
as explained on their blog http://blog.getpostman.com/2017/12/13/keep-it-dry-with-collection-and-folder-elements/
Example of how I set up collection authorization type bearer
This header is being used by my API as type "Inherit auth from parent" and this works with no problems during my requests.
But if I choose to view collection in browser this header is not displayed in the request or examples see screenshot.
Collection documentation as viewed in web
Here is the cURL request in Postman:
curl -X GET \
https://example.api/v1/auth/user \
-H 'Content-Type: application/json'
Is it possible to display the auth header while using the collection settings or I should add the header myself for each request in order to make sure that this is added in the examples and documentation?
Edit:
I've found that if I hover over the Authorization header I get the following message:
This temporary header is generated by Postman and is not saved with your request.
Here is a screenshot from the app with Postman collection temporary headers.
This issue will fix in 2 or 3 mounths.
You can track the issue status in https://github.com/postmanlabs/postman-app-support/projects/40#card-33062423
If you are setting up that JWT Token as request headers then it should get displayed in the documentation. Below are the Steps how i am generating and setting up jwt token:
Login api to generate jwt token.
saving that token as environment
variable Using that variable in each request which requires
Authorization header.
please see the screenshot

Swagger Inspector version of C# call failing when using token

I have the following code:
string tokenValue = "221e0a91-6530-4790-a969-d1da75b0afd2";
// Configure httpClient to use the above token.
httpClient.DefaultRequestHeaders.Add("token", tokenValue);
The subsequent calls (HEAD, POST, GET) all work fine.
When I try to do the same thing using Swagger Inspector, it fails. I am able to get a token using Swagger Inspector site, and I place the token into a HEAD call as follows:
But as I said, the call fails, with "Authorization has been denied for this request." message returned as an XML file.
I also tried the two other options available on the same page: Basic Authentication, and OAuth 2.0/JWT, all with HTTPS. They all fail.
How can I go about understanding why it's failing?
Also: Is what I am using above called "Bearer Authentication"?
I have below 2 things to mention from your screenshot:
Response for HEAD method never contains the response body, it always contains the response headers
for more details of HEAD: HEAD Request
But in your case response-body is also present (maybe of CML content type).
You should use OAuth 2.0/JWT option on the same page to pass the token along with your request.
To answer your question related to Bearer Authentication:
No, the one you are trying to use is not at all Bearer Authentication.
In your case, "token" will be considered as Custom/User HTTP Header.

How to post credentials using POSTMAN client to create a cookie based session

I am using postman client to make REST calls to JIRA API. It says "POST your credentials to http://jira.example.com:8090/jira/rest/auth/1/session" to get SESSION. I tried posting with Form-data, application/x-www-form-urlencoded, raw etc. Nothing worked. which is the right way to do that.
Here is the tutorial i am following: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-cookie-based-authentication
Since you're using postman, I'm assuming you're in a dev environment. In this case, it might be simpler to get going with the auth header, which is a base-64 encoded username/password. From the documentation here:
Supplying Basic Auth headers
If you need to you may construct and send basic auth headers yourself. To do this you need to perform the following steps:
Build a string of the form username:password
Base64 encode the string
Supply an "Authorization" header with content "Basic " followed by the encoded string. For example, the string "fred:fred" encodes to "ZnJlZDpmcmVk" in base64, so you would make the request as follows.
curl -D- -X GET -H "Authorization: Basic ZnJlZDpmcmVk" -H "Content-Type: application/json" "http://kelpie9:8081/rest/api/2/issue/QA-31"
In the Headers section of Postman, add Authorization with Basic <base64-encoded-username:password>
Don't forget to also add the header Content-Type as application/json
(You can use base64encode.org to quickly encode your username/password).
Don't forget to put the string in as username-colon-password (username:password)
If you are on the same UI as I for postman, click Authorization, select an auth type (I used basic auth succesfully), and then enter your credentials. Next click over to the body tab, select raw, and on the drop down menu on the right choose JSON(applications/json), and supply the body as normal.
That is the first hurdle. The next hurdle which may be hit (and the one I am stuck on) is that once your basic-auth gets accepted, JIRA will deny access as part of Cross Site Request Forgery checks (XSRF) with a code 403. I have a ticket open right now seeing if there is a possible workaround to post and put from postman, because using postman and newman would be much much simpler than building an entire plugin which I have to jump through a bunch of hoops to access.
With Postman can simply add withCredentials:true to your request header section.