Mortalus
Mortalus

Reputation: 10712

How to make an Authorized HttpWebRequest to an ASP.NET MVC web app

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

Answers (2)

Mortalus
Mortalus

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

fejesjoco
fejesjoco

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

Related Questions