How to make Azure Storage Static Website URL single-use - azure

I am setting up a static website on Azure Storage that will basically be a single page where a user must fill in a value and then press a button. I generated a SAS that expires after 24 hours, but the other part I am struggling with is to limit access to the generated URL to a single-use only.
I've tried reading through the Azure docs on Microsoft's site but I couldn't find a way to do it
Basically I expect a user to click on the link and it should take them to the html page. But if they try and click on it a second time, it should throw an error saying that they cannot access the page or just give like a 403 response

It is not possible to define a SAS URL with number of times it can be used. As long as SAS token associated with the URL is valid, a user will be able to use that URL.
For this, you would need to use some kind of middleware. Essentially instead of taking user directly to SAS URL link, you take them to a separate link with a unique token. When the user lands there, you check if the token has already been used (by looking up in a database) and then take appropriate action i.e. either allow the user to the final destination or deny access.

Related

Generating download URLs for storage

I have a few questions regarding firebase storage?
I am generating download URLs for firebase storage objects using and admin account (has custom claims) and storing the URL on Firestore.
Users can read the Firestore document to get the URL instead of having to call getDownloadUrl on the client side code.
Q1) I noticed there is a token at the end of the storage URLs. Is this specific to my admin account and is it safe that none admin users can now read this token?
Q2) Furthermore if a non admin user called getDownloadUrl on the same storage path would they receive the same URL as the admin account or a different one?
Q3) If I switch to using getDownloadUrl on the client side would this increase my cost when using firebase storage?
Q4) If i am caching the content by URL and the URL changes it will redownload and not use cache.. Are these download links unique or can getDownloadURL return different URLs on subsequent calls?
Thanks a lot
Edit ---
Sorry I have an additional question
Q5)To move files on firebase storage I currently download them to my local pc and reupload them to another location -- seems very inefficient.
I have seem people using file.move() (as can be seen here.)
Would this be possible to call in a firebase function (as they talk storage rules being an issue in the comments, although its from 2016) and if so how would this be cheaper than my manual download and upload?
Sorry for many questions :)
Q1) I noticed there is a token at the end of the storage URLs. Is this specific to my admin account and is it safe that none admin users can now read this token?
This token is a a random ID generated for this specific file. It won't change, unless you change it intentionally (you can "revoke" the token from the Firebase Console, which will replace it with a new token). Everyone who possesses the URL can view the file whether they are authenticated or not. However, the URL is "hard to guess", so unless you share it with anyone, it will stay secret, practically speaking.
Q2) Furthermore if a non admin user called getDownloadUrl on the same storage path would they receive the same URL as the admin account or a different one?
The returned URL will always be the same, unless you invalidate it in the Firebase Console. If you don't want clients to call getDownloadURL on the files, add a Storage Security Rule that denies reads:
match /path/to/{file} {
allow read: if false;
// Or, if only authed users should be able to call getDownloadURL:
allow read: if request.auth != null;
}
Q3) If I switch to using getDownloadUrl on the client side would this increase my cost when using firebase storage?
A call to getDownloadUrl() does utilize some Google Cloud resources that you will have to pay for, whether you do it server-side or client-side. It's a "Class B" operation (check Google Cloud pricing), and a bit of data transfer.
Q4) If i am caching the content by URL and the URL changes it will redownload and not use cache.. Are these download links unique or can getDownloadURL return different URLs on subsequent calls?
The same URL is return each time, unless you manually invalidate the token. (By the way, the caching policy that sets the Cache-Control header is set on the object as metadata when you upload it.)
Q5) To move files on firebase storage I currently download them to my local pc and reupload them to another location -- seems very inefficient. [..] Would this be possible to call in a firebase function
Yes, you can move files in a Firebase Cloud Function. The Firebase Admin SDKs bypasses security rules.
1) I noticed there is a token at the end of the storage URLs. Is this specific to my admin account and is it safe that none admin users can now read this token?
Depends on what you have at the moment since you can integrate Custom Authentication with Firebase which will allow you to create custom tokens that can be used to sign into the Firebase Authentication service on a client application and assume the identity described by the token’s claim. This can be used when accessing other Firebase services, such as Cloud Storage, etc.
In general your server should create a custom token with a unique identifier.
2) Furthermore if a non admin user called getDownloadUrl on the same storage path would they receive the same URL as the admin account or a different one?
Depends on how you are setting the permissions for the getDownloadUrl. If you have a customized one they can receive a different one but usually it returns a new instance that points to the current reference.
3) If I switch to using getDownloadUrl on the client side would this increase my cost when using firebase storage?
I am not sure about this, I have checked the documentation and there is nothing that would indicate a quota or pricing on this specific method so I would go ahead and assume that it would not do it but I might be wrong on this one.
4) If i am caching the content by URL and the URL changes it will redownload and not use cache.. Are these download links unique or can getDownloadURL return different URLs on subsequent calls?
As specified before, it returns a new instance that points to the current reference so these download links are unique.
5) To move files on firebase storage I currently download them to my local pc and reupload them to another location -- seems very inefficient.
For this question and the last part of your initial post I would suggest you to create a support ticket and ask more details to the Firebase Support Team where you can get more information regarding this since it is more suited for them than to StackOverflow. (https://firebase.google.com/support)

ADB2C custom policy - redirect to source page once signed in

I have created a custom policy for signin and another for sign up. What I would like to do is send my users back to their original source page once they have hit the callback from the policy.
E.g. If they were on a blog page /some-article and hit signin, I would like them to end up back here, rather than just at the base callback url.
I couldn't see any clear way to send in data to a custom policy and return it so I can parse it at the call back. Or if there is a better way?
Azure AD B2C supports the state parameter. You can use this for whatever you want. I generally use it to save the last visited url via base64encoding.

Azure Active Directory graph api - How to regenerate expired page token

I am using Azure AD graph REST API to get all users on the Azure Active Directory. I am also using paging while getting those user.
At the end of each page, api returns token for the next page. Which is used to get next page of users.
It looks like this - "odata.nextLink": "directoryObjects/$/Microsoft.DirectoryServices.User?$skiptoken=X'226370740200010000003E3ACDE316230633836636636373430323861666235626436306537366132306139407361696C706F69AEFDE746465762E6F4F4F4F418F736F66742E636F6D29557365725F383461663866351238412782482433372D626439312D336239633930373536383464B900CCCC00001111000000'"
}
For some reason if there is delay in using this next page token, it expires. API throws error 'Bad Request The specified page token value has expired and can no longer be included in your request.'
So how to regenerate valid page token for next page without starting again from the beginning ?
What is the default validity for the page token ? I guess it is 1 hour. Is it possible to increase this time ?
Looking around on existing graph documentation, there is no mention of any explicit manner to extend this token.
Considering there does not seem to be a way to extend it, you should make your app code advance as much pages as it did (caching it somewhere), to continue from there.
You should also consider restarting from the beginning, as one hour can be long enough to have your user list potentially been modified.

Obtaining Instagram Access Token

We have a client who has a simple Instagram feature on the site to pull photos by a certain tag. They just noticed it isn't working. Getting an error - invalid access token. I guess since the 1st because of the updates. We didn't used to need an access token since we're not doing anything with users - just tags.
Now it looks like we need one and the documentation makes zero sense on how to obtain one. And it seems like they're not accepting most apps. The app is in sandbox mode too. So I'm assuming it's because it got switched to that? Got no notification of this happening.
The first step in documentation to get an access token is "Direct the user to our authorization url." What does that even mean? There's not a link provided or anything. It also says "Company Name, Contact Email and Privacy Policy URL are required to start a submission." Our app doesn't have a privacy policy... it's just a simple tag feed. I don't understand why everything is so complex to have a simple tag feed.
Is there a wait time to get the app approved..if it gets approved... Do I have to have it approved before getting an access token? This isn't outlined anywhere.
You got it right. As of June 2016 any Instagram API calls require an access token.
Getting an access token is described in the documentation. App approval is not required.
There are two ways to get one: server-side or client-side. The second option (called implicit authentication) can only be used when implicit OAuth is enabled in the client settings (Manage Clients > Edit Client > Security > Disable implicit OAuth). It is disabled by default.
In either case you need to redirect the user to the authorization URL to obtain an access token.
The URL for explicit mode (server side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
The URL for implicit mode (client side) is:
https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=token
After this you will be redirected to the REDIRECT-URI, which will be passed an argument. For explicit mode this will be a query string with a code, while for implicit mode you will get the access token directly as a hash:
http://your-redirect-uri?code=CODE
http://your-redirect-uri#access_token=ACCESS-TOKEN
For implicit mode you can then get the access token from the window.location.hash in Javascript.
For explicit mode, however, you need to further process the code to obtain the access token. You can read how this can be done in the API Documentation. I'm not going to take this any further here.
The problem is that every user who wants to see your feed needs to login to Instagram (and have an account) in order to view it. In your case this might not be desired. However, there are a few options to get around this (rather annoying) problem:
You can reuse your own (already obtained) access token(s) to display the Instagram feed for every user. You will need to be aware of rate limits for each token. For sandboxed apps this is 500 API calls / hour, while live mode allows 5000 API calls / hour. [source] You could store tokens in a table and use them in a round-robin manner, to allow more API calls. This involves manually obtaining a bunch of tokens which your application can use (the more the better). This might not be the ideal solution considering Instagram doesn't warrant access tokens to have an unlimited lifetime.
You can retreive JSON data without authentication by appending /media/ to a user page URL, as described in this post. No tokens or client IDs are required for this to work. However, this only works for users, not for tags. Besides, Instagram doesn't document this feature so it is not garanteed to work in the future.
You can use an aggregator like Juicer or Dialogfeed instead which will handle access tokens for you. This is usually not free of charge.
I'm also in the process of making an Instagram feed for my website, and this is what I concluded from my research. Please bare with any errors I made.
Edit: Here are some more limitations for sandbox apps.
In sandbox mode you can only access data from sandbox users (thus users who received a sandbox invite). This means that:
Media retreived by user, e.g. /users/{user-id}/media/recent, will return an empty response if the user is not any of the sandbox users.
Media retreived by tag, e.g. /tags/{tag-name}/media/recent, will only contain tagged media belonging to sandbox users.
Thus, for a tag feed to work, it needs to be live (reviewed and approved). If you don't want to do this, the only alternative is to use an aggregator as I mentioned above.

How does account validation work?

Usually when you create an account to some webpage they send you an email with a link in order for you to validate your account.
If you click that link then you account is validated and thats the end of it.
How does this work?
Is that url unique for every new user so they know who visited what?
This is not a web service related question, however I can conceptually guide your through what you need to do.
When a user registers their information will probably be captured into some user table in a database somewhere. This user is marked as pending. The system can then generate a unique id i.e. a GUID which is stored next to the user entry in the database. This GUID if properly constructed will be impossible to guess. This GUID is then added as a GET parameter to the URL that you in an email to the user.
For example you might have the URL:
http://example.com/activateuser?confirmuid=5e706449-2cbf-4938-8109-fb564c196d8f
Thus every user will use the same URL with different confirmuid parameter. This URL will then post the confirmuid to the page where you can then use this value to look up the user in the database and then active the user or move it from a pending state to an active state.
Simple right.

Resources