I have an api gateway with custom domain names set up, it works fine if I visit the custom domain name but if I visit the API Gateway domain name (https://xxxxx.execute-api.us-west-2.amazonaws.com) directly I just got:
{"message":"Forbidden"}
My understanding is that custom domain name here is just like an alias to the original API Gateway domain name and is just a prettier name for it so I should be invoking the api gateway by either of them?
API Gateway REST can be invoked in two different ways.
Directly with execute api invoke URL suffixed by stage name.
Example: https://ab11cde222.execute-api.us-east-1.amazonaws.com/dev , where ab11cde222 is api id and dev is stage name.
Custom Domain: Adding a custom domain with in API Gateway and API mapping pointing to a particular stage and a route53 A record entry for hosted zone.
Since we can point the domain directly to a stage in api mappings, we don't have to suffix stage name when we use direct domain name.
There are many reasons why {"message":"Forbidden"} can occur as listed here, every reason either points to a call of an invalid/non-existent api or missing/invalid keys. Since the direct domain name is working fine, it seems like missing stage name suffix is most probable cause.
Related
Question
Can I get nginx to call another microservice inside of AKS k8s prior to it routing to the requested api? - the goal being to speed up requests (fewer hops) and simplify build and deployment (fewer services).
Explanation
In our currently deployed Azure AKS (Kubernetes) cluster, we have an additional service I was hoping to replace with nginx. It's a routing microservice that calls out to a identity API prior to doing the routing.
The reason is a common one I'd imagine, we recieve some kind of authentication token via some pre-defined header(s) (the standard Authorization header, or sometimes some bespoke ones used for debug tokens, and impersonation), we call from the routing API into the identity API with those pre-defined headers and get a user identity object in return.
We then pass on this basic user identity object into the microservices so they have quick and easy access to the user and roles.
A brief explanation would be:
Nginx receives a request, off-loads SSL and route to the requested service.
Routing API takes the authorization headers and makes a call to the Identity API.
Identity API validations the authorization information and returns either an authorization error (when auth fails), or a serialized user identity object.
Router API either returns there and then, for failure, or routes to the requested microservice (by cracking the request path), and attaches the user identity object as a header.
Requested microservice can then turn that user identity object into a Claims Principal in the case of .NET Core for example.
There are obviously options for merging the Router.API and the UserIdentity.API, but keeping the separation of concerns seems like a better move. I'd just to remove the Route.API, in-order to maintain that separation, but get nginx to do that work for me.
ProxyKit (https://github.com/damianh/ProxyKit) could be a good alternative to nginx - it allows you to easily add custom logic to certain requests (for example I lookup API keys based on a tenant in URL) and you can cache the responses using CacheCow (see a recipe in ProxyKit source)
My API endpoint type is edge-optimized. I have a custom domain name API like www.example.com and I want to add a new CloudFront which to block specific countries request in front of my API Gateway.
How to add a new CloudFront in front of my API Gateway and use the same domain name (www.example.com)? I am confused. Is it possible to do that?
Any advice will be appreciated.
Yes it is possible to do that. You should follow the following steps.
Create a origin for your API Gateway inside your CloudFront
distribution. There you should enter the endpoint of your API Gateway
for the origin domain name.
Then you need to create a behavior inside
the CloudFront distribution which forwards requests that match a
specific path pattern to your API Gateway. (Make sure that you put
the Minimum TTL to as 0, since we don't want to cache the the API
requests)
See the following documentation for further reference.
Custom origins
Cache behaviors
My goal is to create a REST API Integration from Salesforce to SAP application.
SUCCESS Through Chrome APP
1. All I need to do is retrieve values from sap application through the REST API. When I tried to use the Chrome APP 'Advanced Rest Client' and have passed the appropriate URL and Content with POST method I was able to retrieve the values from local server database.
For EG : If I pass request 92126 then I was able to get response 'SAN DIEGO' which is correct.
Here is the link (https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=en-US) for Advanced REST Client.
PROBLEM from Salesforce :
I had created a remotesite setting
When I created this REST class in SAlesforce and tried invoking the End Point then it's throwing this error.
System.HttpResponse[Status=Service Unavailable, StatusCode=503]
As the web api url which is provided to us is in local sql server i.e hosted in private, as we know in Salesforce for making callouts the URLs must be in public. But the URL is in private only for the security reasons not hosted in public. We should achieve it, any way is there to achieve it? What change should be done in Salesforce or server to communicate to each other, and allows to make the callout?
It is most likely that you endpoint does not allow access from outside some ip range which you indicated by saying it's not public. Salesforce is a SaaS application hosted outside the domain that your service is on. In order for Salesforce to access that endpoint resource you need to whitelist Salesforce IP ranges, which can be found here.
Whitelisting allows Salesforce to access the resource. The only caveat is that because Salesforce is multi-tenant it means that any instance of Salesforce on the range that you whitelist would have access to your endpoint. If this is not ok, you might want to add some sort of header or sign the request to the call to that identifies your Salesforce instance uniquely from any other instance to validate that the call originated from your Salesforce org.
(I am linking to the article instead of pasting the IP ranges here because these may change in the future).
I'm having issue using DocuSign API. when I send a PDF via SOAP API. (I am using the method CreateEnvelopeFromTemplates, the templates are on your server) When the user received the envelope (PDF) the fields are not there. But when I send via the WEB they do have the fields.
I was not adding the Role to the API, now I'm but still not showing the fields.
Should I use the method CreateEnvelopeFromTemplatesAndForms instead the other one?
I believe you're using the right method (CreateEnvelopeFromTemplates). The most likely reason that the fields (tabs) are not being displayed when you create the Envelope via the API is that the recipient Role Name(s) being specified by the API request does not exactly match the Role Name(s) specified by the Template itself (with which the tabs are associated). Make sure spelling, spacing, and case of Role Name(s) specified by your API request matches exactly with what's specified by the Template.
I have created an API using AWS API Gateway. Now I want to log each of the request on each method of each resource. Also, I need the source IP address of the client accessing the route. How can I accomplish this without writing custom code in the API functions ?
The default CloudWatch logs for your API should include all headers, including the X-Forwarded-For header which will contain the source IP address. (See http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-stage-settings.html)
If you need custom logging you will need to implement this in your Lambda functions. You could take advantage of something like Apex or Serverless and write some automation to manage your Lambda functions and share duplicate code.