Reputation: 10712
I have an ASP.NET MVC web app that needs to allow a public API for downloading files. Here is the action code:
public ActionResult DownloadFile(int id)
{
var item = _context.GetRepositoryFileByID(id);
if (item == null)
{
return HttpNotFound();
}
var filePath = Path.Combine(AppConfig.FilesRepositoryStorageRoot, item.IntrenalFilePath);
return File(filePath, "application/pdf");
}
this method is the a controller with an [Authorize(Roles = "Administrator,User")]
attribute set to it so only logged in users may access this action
now this action should allow users to make a request using the following code:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(fileDownloadUrl));
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
the thing that I am missing here is how do I pass an authorized HttpWebRequest
to the DownloadFile
action.
every thing I have tried will return the login page because the application cannot authorize the user and allow him to access the DownloadFile
action.
I have tried to pass this Cookie value to the website that request the file using the following code
var authCookie = FormsAuthentication.GetAuthCookie(User.Identity.Name, true);
var authCoockieValue = authCookie.Value;
Then the website have used this value like this:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(fileDownloadUrl));
request.Headers[HttpRequestHeader.Authorization] = "Bearer " + authorization;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
but this did not work.. I have also tried to pass the header with "Basic" instead of "Bearer" tag but it field as well.
I cam to terms with that I do not really understand how does an ASP.NET MVC application uses the [Authorize]
attribute with FormsAuthentication
so I humbly ask for your help...
Upvotes: 4
Views: 7047
Reputation: 10712
I have found the solution.
You need to add an Authentication Cookie to the HttpWebRequest
like this:
Uri fileDownloadURI = new Uri(fileDownloadUrl);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fileDownloadURI);
request.Headers[HttpRequestHeader.Authorization] = "Bearer " + authorization;
var authCookie = FormsAuthentication.GetAuthCookie(User.Identity.Name, true);
Cookie requestAuthCoockie = new Cookie()
{
Expires = authCookie.Expires,
Name = authCookie.Name,
Path = authCookie.Path,
Secure = authCookie.Secure,
Value = authCookie.Value,
Domain = fileDownloadURI.Host,
HttpOnly = authCookie.HttpOnly,
};
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(requestAuthCoockie);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Upvotes: 5
Reputation: 11903
Depends on what kind of authentication you are using. Generally, just simulate whatever the browser is doing when a user is logging in (you should know based on your code+web.config, or you can use a web debugging tool to capture the web requests). In case of a login form and cookies, just call the login action from your HttpWebRequest, and use a CookieContainer so that the resulting cookie is persisted to the next request. Or you could create a new authentication API, or even a whole new web application with different authentication.
Upvotes: 0