Question

I am looking for a way to allow access to certain Excel files to specific users only.

This is the scenario:

I have an ASP.Net 4 application, which Forms authentication. I would like to be able to give access to ever growing sets of Excel files to a number of users. Each user is allowed access to one of the sets.

I can easily arrange a navigation page, which will only show hyper-links to the Excel files the user is allowed to see. However, by guessing URL's, files from others could be retrieved as well.

I tried the following scenario: Set up a base folder for all Excel files with inside it a folder for each user. In each folder, a web.config file is placed. On the main folder, this contains the following:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <authorization>
            <deny users="*" />
        </authorization>
    </system.web>
</configuration>

Each subfolder this:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <authorization>
            <allow users="<username>" />
        </authorization>
    </system.web>
</configuration>

This works well for any .aspx files inside the folders, but not for other types of resources, like my Excel files. Access to those is always granted. I assume that this is caused by the fact that these files are not handled by the ASP.Net worker process.

What would be a good way to arrange access only to the correct user? I am thinking about storing the Excel files outside the ASP.Net application's virtual directory and writing some ServeExcel.aspx page that will output the Excel file using the Response stream. Are there better ways to do this?


Addition, in response to the comment by BrOSs

I read the 'Walkthrough: Creating a Web Site with Membership and User Login' and created a test site. In stead of following all steps, I did not start with an empty project template, but with a ASP.Net Web Application and caught up with the walk-through in step 'Creating the Members-Only Page'. I followed it up to and including step 'Adding New Users '. I created two users, user 'member', granted access to the folder Membership, and another user 'visitor', denied access to this folder. In addition to the steps in the tutorial, I added an Access rule 'Deny users'.

When running the web application, the member page ~\MemberPages\Members.aspx is visible to 'member' and not to 'visitor'.

After that, I put a file test.xls in the MemberPages folder. To my great surprise, access to this file is also denied to 'visitor' (and anonymous users)!

Note added 2013-01-03: The true reason for the above to protect Excel files, is that I used the internal Visual Studio Development Server. On a server, IIS will be used and by default IIS itself will serve Excel files. I tried to modify the configuration of IIS 6.0 and 7.5 by modifying ISAPI filter configuration, but in the end this seemed to sensitive to misconfiguration, so I applied the solution suggested by Joe.

This is a big difference from my experiences with my own web application and I have found a significant difference between the projects.

My project does not use ASP.Net Membership, but uses a custom user table. Also, custom code is present in the global.asax.vb file:

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
    If (Not (HttpContext.Current.User Is Nothing)) Then
        Dim objLogin As New Person(ConfigurationManager.AppSettings("DBConnection"))
        objLogin.AuthenticateUser(HttpContext.Current.User.Identity.Name)

        Dim strRoles(10) As String
        strRoles(0) = "user"
        Dim objPrincipal As New System.Security.Principal.GenericPrincipal(objLogin, strRoles)
        Context.User = objPrincipal
        System.Threading.Thread.CurrentPrincipal = objPrincipal
    End If
End Sub

Note: the Person class implements the System.Security.Principal.IIdentity interface. I am not sure if similar code is executed in the test project, but at least nothing like it in the Global.asax.cs or Login.aspx.cs files.

I attached the debugger to my project and found that Application_AuthenticateRequest is executed on each request for an aspx file, and every time, HttpContext.Current.User is nothing. During a request for an Excel file, this code is not executed and I assume this is why the file is served without any limitations imposed by the web.config authorization settings.

I found another post: Object persistence (between post-backs) in ASP.NET and will delve into it and see of it can help me.

Still, since the I am writing code that adds some custom functionality to a sort of framework ASP.Net application, used by many projects, I think changing the global.asax file will be outside acceptable modifications. Therefore, I am still considering the ServeExcel.aspx/ashx option.

Was it helpful?

Solution

Using a ServeExcel.aspx page (or ServeExcel.ashx handler) to handle authorization and serve the Excel files is a reasonable approach.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top