I need to create a S3 presigned url that expires after one use.
I have tried to create presigned url with near expiration date, but in my case is not enough.
is there a method to do this?
Related
The access level of my container is 'Private (no anonymous access)'. I prefer this access level as I only want authorized users to view my content. However, when I try to access a file via the container URL I get a ResourceNotFound error.
I guess there are alternative steps to authenticate the validity of the request. Can someone please help me out by letting me know the steps to get a file displayed.
My front end is Angular/HTML.
This is expected behavior. You can't directly access a blob if it is in a blob container with Private ACL.
What you would need to do is create a Shared Access Signature (SAS) on the blob with at least read permission and use the SAS URL of the blob. You can create a Service SAS on the blob.
The way it normally works is that you would create a SAS on the blob in your backend API and then pass that SAS token/URL to your frontend.
I have a ASP.NET MVC (NOT ASP.NET Core) single page application with angular js on the front end.
My client (browser) talks to server through ASP.NET Web APIs. Now, the web application is on https but anonymous. There is no login/ user authentication.
The web app is in the form of a wizard where user can go back and forth and add or update input fields on the web page. The form input values are then updated on the server through Web API.
I'm looking for a way to secure my Web API calls alone, especially the POST/ PUT requests. In summary, I want to prevent any user calling my Web API directly from POSTMAN or Fiddler. The Web API, though anonymous can be only called from the browser session where the request originated.
What are options do I have to achieve this?
Can I use Anti-Forgery token here (without authentication)?
One way, I can think of achieving this is to add a custom header to each request and store some kind of session key in the header. Then, validate the custom header on every request I received from client. Are any other ways of achieving this out-of-box or some proven library without going for custom solution?
If I have to go for the above custom solution, what are the pitfalls or potential issues I need to be aware of?
First of all when you remove login and there's no authentication mechanism in your application, there's really no way to secure anything, because anyone can access your APIs. I think what you want is to make sure that your APIs are called only from your own website. Unfortunately you can't completely achieve that, since your web APIs are http/https, and anyone, from anywhere (like postman, fiddler, ...) can create a http request and call your API.
All you can do is to make it harder for your API to response to requests, like using Anti-Forgery as you mentioned.
And also I suggest you add a cookie for your application and check that cookie in every request, in this case it's more complicated ( not impossible ) to call your API using Fiddler or Postman.
And last I suggest that you use CORS, so browsers would only allow your domain to call your APIs. So nobody can call your APIs in a browser from different domain.
Based on answer from #Arvin and comment from #Evk, here's how I plan to proceed:
Once, the user starts the anonymous session generate a GUID using regular Guid.NewGuid() method and save it in DB to identify the request (I'm doing this now). However, as mentioned here,
GUID can be unique but they are not cryptographically secured.
Hence, instead of using plain-text GUID, encrypt it with current timestamp as token and append it with request query string.
For every subsequent API request, read the token from query string, decrypt it and validate it as follows:
Check the timestamp. If the time difference is more than pre-defined time (i.e. token expired), reject the request
Validate the unique id (GUID) against DB
Since, I'm not using plain text GUID anymore, the URI would not easy to guess.
Additionally, with the timestamp, URI is invalidated after sometime. While theoretically it is still possible to call the API through Fiddler but this should make it very difficult for the attacker, if not impossible.
As a further security measure, I can also add Anti-Forgery token to the request
As per my understanding this helps solving my underlying problem and with this approach, I may not even need add a cookie to secure my anonymous session.
Love to hear from you all if this approach looks good and how can it be improved.
I also once had the weird need for having session functionality on WebAPI and created an OWIN Session middleware that does exactly what you're aiming for.
The library is called OwinSessionMiddleware and is available on github and NuGet.
Usage
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseSessionMiddleware();
// other middleware registrations...
app.UseWebApi();
}
}
You can also pass some options to further tweak cookie-name, add a database backed session store (instead of in-memory), add your own session id generator (instead of default id generator which is based on GUID + secure random part generated by RNGCryptoServiceProvider).
The unique session id itself is stored as a secure cookie and the session is restored automatically by the middleware on each request.
There are extension methods you can call inside your API controller to get and set session data:
public SomeApiController : ApiController
{
public IHttpActionResult MyAction()
{
var requestCount = Request.GetSessionProperty<int>("RequestCount");
Request.SetSessionProperty("RequestCount", ++requestCount);
}
}
Create Anonymous JWT token with some claims related to your scenario, Sign it with some key, Use that as in cookie (Http Only) or As bearer token. To make it little more harder further combine it with some cookies.
1)verify token signature and
2) Verify token expiry time
3) Verify Claim(skey) against cookies(skey)- no database storage required everything is in ur JWT token.
I am working on a project in which i need to create shortened url. I am using google url shortener. Is there any way to retrieve all the urls created using the google account or using the api key
You should use this.
GET https://www.googleapis.com/urlshortener/v1/url/history
In the headers, set Authorization header to Bearer <authtoken>
Make sure you have a valid OAuth Token. Retrieving the Shortened URL History List of a user requires an access token.
You could generate one here for testing it out
I am working in AWS S3 with upload and download. I have generated Pre signed URL with expiry date. It is working fine. Here i am going to delete files in S3 after expired that is no longer needed.
I had a link. How to check the link is expired or not using C#?
Any one assist me to handle it.
Thanks in advance.
Check pre-signed URL already expired.
HttpResponseMessage response = await httpClient.GetAsync(awsUrl, HttpCompletionOption.ResponseHeadersRead);
if (response.StatusCode == HttpStatusCode.Forbidden){}
I need to implement a operation in which the user requests a file which takes sometime to be generated ( 2 - 4 minutes). After that, the user needs to download the file, preferentially through ASP.NET ( to make use of the browser download facility). Only the specified user can download this file.
Here is how i tried to do it:
First, I built a duplex wcf service. The user calls it with the data it needs and then it starts the file generation, notifying the progress through the callback channel. In the end, the service is supposed to send to the user a url, token which he will use to download the file. This part works fine.
I saved the file to a temp folder in the asp_data folder, to prevent it from being accessed directly. Then I created a aspx page to receive the token ( whatever it is), validate it against the current user, the defined expiration, and replace the response with the file.
Then the things got messy. I do not know the right way to generate the token through WCF, return it to the client and use it the access the download page. I tried two different approaches, but I think I'm giving up on both:
Generate a guid for the file, encrypt it inside a FormsAuthenticationTicket (with the user information and expiration) and send it to the client. The client then uses the ticket encrypted string as the token to the download page, which validates the user in the ticket against the current one , check the expiration, extracts the guid and sends the file back. The problem is that the generated encrypted string gets really big, unusable in a url.
Generate a guid for the file, save it in ticket ( with validation data and the path to the file) in the httpcontext session. the wcf service then passes the guid to the client, who uses it to access the download page. The download page checks the session, retrieves the ticket, serves the file. The problem is I'm having some trouble acessing the session in the WCF operation. The user requests the file, the server starts a thread to generate the file and make the callback calls, so the first server call returns (nothing). When I've finish generating the file with success, the callback thread tries to access the session, save the ticket and return the guid to the user in a 'FinishOperationXXX' callback. I cant access the session, though, because it seems to be no longer available to the callback thread.
I don't want to use a database to do this, and I'm trying to avoid downloading the file throught the WCF itself, but I need to get this working. I guess I'll manage to do it somehow, but I wonder:
Am I doing this the hard way?
Do anyone have a clue about implementing something alike?
Why do you need encryption and a FormsAuthenticationTicket?
Wouldn't it work well enough to just name the file with the type of file, user's userid and a timestamp (filetype_userid_timestamp.ext) and only allow users to download files that contain their userid in the middle field?
(type of file being different for each page doing this in case you had more than one...)
Authentication for the user should already be handled by the session right?