Asp.net - access some folder on file share based o

2019-07-10 05:07发布

问题:

I have an asp.net web application with forms authentication and users (credentials) are checked against active directory, username is actually samAccountName attribute from AD. Now I need to enable users to get access to some files which are located on file share, where each user has his own folder.

First proof of concept works like this:

  1. appPool in IIS is configured to run under some domain user, and this user was given R/W access to file share and all user folders

  2. when the user logs into web app only content of the folder on the path "\\myFileServer\username" is visible to him. And same when uploading files they get stored to "\\myFileServer\username".

While this works, doesn't seem to be secure at all. First issue is that user under which application pool runs has access to folders from all users. And even bigger concern is that only username determines to which folder you have access.

So my question is what is the correct/better way to doing this ? I was reading about impersonating the user, but this is not advised anymore if I understood correctly ? And I don't have Windows authentications since the web application must be accessible from internet.

回答1:

I recommend not running the application under a user account, but creating an application specific account under which it runs with the proper R/W rights, and separate the person who gives these rights from the development team.

Within the application's authentication: after you receive a GET/POST request, you can verify the path to which the current user would read/write data, and cross-reference this with the path the user is authorized to read/write from. If these are incorrect, return a 401 NOT AUTHORIZED response, else, carry on the operation as you do now.

If your endpoints are protected properly, and the application runs under its own account, I don't see any harm in the setup itself. This still however gives the developers a way, through the application, to indirectly access other user's files. Based on how tight these checks must be, you could add additional controls, (like only allowing the application to connect from the production server, and only allowing server transport in a controlled way).



回答2:

From the Description of your Problem i think Custom HttpHandlers are the right choice for you. You didn't mention what type of files will be present in your Folder , for brevity i will answer by assuming it will be having PDF files.

As you were mentioning that your application will be having different users so for this you need to use .NET built-in authentication manager and role provider. With a simple security framework setup, we'll place a PDF file in the web application, behind a web.config protected folder.then create a custom HTTP handler to restrict access on the static document to only those users who should be allowed to view it.

A sample HTTP Handler:

public class FileProtectionHandler : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        switch (context.Request.HttpMethod)
        {
            case "GET":
            {
                // Is the user logged-in?
                if (!context.User.Identity.IsAuthenticated)
                {
                    FormsAuthentication.RedirectToLoginPage();
                    return;
                }
                string requestedFile = 
                 context.Server.MapPath(context.Request.FilePath);
                // Verify the user has access to the User role.
                if (context.User.IsInRole("User"))
                {
                    SendContentTypeAndFile(context, requestedFile);
                }
                else
                {
                    // Deny access, redirect to error page or back to login 
                     //page.
                    context.Response.Redirect("~/User/AccessDenied.aspx");
                }
                break;
        }
    }
}

Method SendContentTypeAndFile :

private HttpContext SendContentTypeAndFile(HttpContext context, String strFile)
{
    context.Response.ContentType = GetContentType(strFile);
    context.Response.TransmitFile(strFile);
    context.Response.End();
    return context;
}
private string GetContentType(string filename)
{
    // used to set the encoding for the reponse stream
    string res = null;
    FileInfo fileinfo = new FileInfo(filename);
    if (fileinfo.Exists)
    {
        switch (fileinfo.Extension.Remove(0, 1).ToLower())
        {
            case "pdf":
            {
                res = "application/pdf";
                break;
            }
        }
        return res;
    }
    return null;
}

Last step is that you need to configure this HTTP Handler in the webconfig , and You can see the more info here

Here is the complete Source Code



回答3:

You're architecture (and assumptions) seem good for a low/mid security level, but if the nature of your data is very sensitive (medical, etc) my biggest concern about security would be controlling the user sessions.

If you're using forms authentication then you're storing the authenticated identity in a cookie or in a token (or if you're using sticky sessions then you're sending the session Id, but for the case it's the same). The problem arises if user B has phisical access to the machine where user A works. If user A leaves it's workplace (for a while or forever) and he doesn't explicitly close it's session in your web app, then his identity has been left around, at least until his cookie/token expires, and user B can use it since the identity system of ASP.NET hasn't performed a SignOut. The problem is even worse if you use tokens for authorization, because in all the infamous Microsoft implementations of the Identity System you're responsible of providing a way to invalidate such tokens (and make them dissapear from the client machine) when the user signs out, since they would stay valid until it's expiration. This can be addressed (but no completely thus not very satisfactorily for high security requirements) issuing short living refresh tokens, but that's another story, and I don't know if it's your case. If you're going with cookies then when user A signs out it's cookie is invalidated and removed from the request/response cicle, so this problem is mitigated. Anyway you should ensure that your users close their sessions in your web app or/and configure the cookies with short lives or short sliding expirations.

Other security concerns may be related with CSRF, wich you can prevent using the Antiforgery Token infrastructure of ASP.NET, but these kind of attacks are methods that are very far away from the tipical user (I don't know anything about the nature of your user and if your app is exposed to public on internet or it's only accesible on an intranet), but If you worry for such specialised attacks and have so sensitive data, maybe you should go with something more complex than forms authentication (two factor, biometrical, etc)