Web app to display image from S3 using AWS policy - html

Background
We have a web app that uses aws-sdk for JavaScript to allow login with AWS Cognito.
We want to allow user access to files on S3 based on AWS policy.
Using AWS.config.credentials = new AWS.CognitoIdentityCredentials(...) we were able to perform a login, and receive a token
Using this token we perform listObject on the bucket.
The problem
After a successful login and listObject on S3, when setting the src attribute of a <img /> tag to https://MY_BUCKET.s3.amazonaws.com/my_file.jpg we get:
403 (Forbidden)
It seems that the client request header does not contain the aws-token retrieved by aws-sdk.
What we've tried
Going through the Prerequisite Tasks in this article
Going through these examples
This solution from StackOverflow (yields Maximum call stack size exceeded). Besides, it seems like a client side CPU intensive solution.
The question
What is the cleanest and easiest way to use CognitoIdentityCredentials to allow display of images from S3 bucket inside a web page?

You can create policy with IAM like so:
http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_cognito-bucket.html
The Javascript SDK helps get credentials, cache them, and is a wrapper around Cognito APIs. http://docs.aws.amazon.com/cognito/latest/developerguide/getting-credentials.html#JavaScript

Related

Hiding the Video URL in a HTML page using Azure Api management service

I have stored a video file in BLOB storage. I need to stream this video but, I do not want users to go into developer mode and copy/paste URL on a browser so they can download it.
I have tried many ways to control this but I have failed. I used SAS token with an expiry, but, users are still able to download the content within that expiry period.
My latest approach is to hide the SAS Token enabled video URL behind Azure API Management Service. This will give me a different URL (which is not the BLOB storage URL) which I will expose on the HTML page. Will this approach work ?
NO, we cannot hide the backend information in a Web. You can’t hide anything that your app running on a clients Browser. Instead of that you can secure your backend service.
There are some alternate ways to do that, but we don’t hide anything on a web.
1. Mask URLs in content
The redirect-content-urls policy re-writes (masks) links in the response body so that they point to the equivalent link via the gateway. Use in the outbound section to re-write response body links to make them point to the gateway. Use in the inbound section for an opposite effect.
<redirect-content-urls />
Refer for Mask URLs in content
2. Set backend service
Use the set-backend-service policy to redirect an incoming request to a different backend than the one specified in the API settings for that operation. This policy changes the backend service base URL of the incoming request to the one specified in the policy.
<set-backend-service base-url="base URL of the backend service" />
Or
<set-backend-service backend-id="identifier of the backend entity specifying base URL of the backend service" />
Refer Set backend service
Other wise you can encrypt your video data to secure a backend
To know the possible ways see here
If a client has a valid SAS can access your storage account that was permitted by the SAS. It’s important to protect a SAS from malicious or unintended use. For that use discretion in distributing a SAS, and have a plan in place for revoking a compromised SAS.
Refer: SAS for blob

How can I send get request directly to an API?

I sniffed the network traffic coming out of an app that displays real time data. I am trying to get access to the api to display the same real time data on a website that I am working on currently. I was able to view the get request and the response using fiddler and I then sent a get request directly using the url. However, my get request was blocked by CORs policy. I'm a beginner and would like to know how to access the API.
If the server that's hosting the API doesn't supply COR headers that explicitly allow this, you're not going to be able to make these requests via your browser. I'd recommend making the requests on your server instead of in the browser, because that's not bound by CORs settings.

How to use Yammer API call without CORS?

I'm running a Yammer Embed script on my client's Sharepoint Online tenant, which displays conversations/messages.
I am looking to create a dropdown box that can be used to filter the messages based on which Yammer groups the user is apart of.
To make the dropdown dynamic, I need to make a call to the Yammer API to get the groups of the current user - I've been using the API call:
/api/v1/groups.json?mine=1
This gives back valid JSON with correct data when browsed to directly, however when called inside the Sharepoint Online tenant I get the following error:
XMLHttpRequest cannot load
https://www.yammer.com/api/v1/groups.json?mine=1. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://client.sharepoint.com' is therefore not
allowed access. The response had HTTP status code 401.
My question: Is there a way around this? I assume Yammer would need to implement CORS for this call (doubtful on getting them to do this). I've also tried the api.yammer.com/... URL to no avail.
Cheers!
Are you using the JavaScript SDK? With that you register your JavaScript origins (where you host your custom code) on the Client Applications page, and then use the JS SDK to handle the authentication and authorization.

Displaying private HTML file from AWS S3

I'm currently hosting a static website on AWS S3. I have parts of the website that I only want AWS Cognito authenticated users to access. These parts of the S3 bucket are restricted to certain roles. As I understand it, once a Cognito user has received their temporary AWS credentials, I need to use the S3 sdk to load the restricted object (index.html) from S3 and display it in the webpage. Is this the correct approach, and once I have the object back from S3, how do I go about loading it into the webpage? Thank you!
You will need application logic that runs in the back-end to control your security and to store/retrieve data. While much of this can be done from the browser, it is open to hacking. Therefore, you need your access control logic in the back-end.
Option 1: API Gateway and Lambda functions
You can have a static web page served out of Amazon S3, which makes API calls to Lambda functions via API Gateway. This is known as the serverless model.
Here's a sample diagram from the Serverless Code website:
Basically, Lambda functions receive the request, determine whether the user is authorised, determines what they would receive back (eg a pre-signed URL to a different page) and sends it back to the web page. The benefit of this design is that it does not require any servers.
Option 2: Amazon EC2 servers
Alternatively, you can run Amazon EC2 instances fronted by an Elastic Load Balancer. This is traditional application design allowing you to use many different frameworks. However, there is an on-going cost for the servers even when nobody is using your application.

Using XMLHttpRequest within a Google Sheet Sidebar

I'm trying to make a REST call to a server that has restricted IP access. Therefore, I need to make the call from the client. To do so, I'm trying to use the XMLHttpRequest object within an HTML page loaded in the Google Sheet Sidebar. When I call XHR.send(), however, I always get an exception of the form:
"NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://some.host.com/'."
Does XMLHttpRequest not work within a google sheet sidebar? Is there an alternative?
Thanks.
When you say that the server you're talking to has "restricted IP access" do you mean only whitelisted IP Addresses can call it? Have you added Google's servers to that whitelist?
This answer provides details:
Google App Engine - list of IP addresses?
As does the FAQ here
https://cloud.google.com/appengine/kb/
(see question "Static IP Addresses and App Engine apps").
I've discovered that making XHR requests from the sidebar is in fact possible.
The problem I was running into was that the browser was blocking the request due to it being a cross-origin request. And, unfortunately, I'm not able to add google to the list of acceptable origins on the server I'm communicating with. So, I may be stuck for my particular use case.