简体   繁体   中英

Use NTFS security in IIS for given user

I have a website that is attempting to retrieve documents from a folder that's restricted to specific AD groups/users. Given a user that's authenticated using Windows Authentication, I wish to attempt to check if they have access to a specific location and display/hide documents as needed. I was under the impression that using Windows Authentication and ASP.NET Impersonation would use the current user's credentials when executing a request, rather than the Application Pool's credentials, but this doesn't seem to be the case because I'm an admin capable of opening the restricted folders in Windows Explorer, but I can't read them from my application.

Is there any way to use the current requesting user's credentials to access files on the local filesystem?

In my web.config:

<appSettings>
    <add key="documentFolder" value="C:\Users\auser\source\repos\myapp\myapp\docs\folder1,C:\Users\auser\source\repos\myapp\myapp\docs\folder2,C:\Users\auser\source\repos\myapp\myapp\docs\secured" />
    <add key="securityFolder" value="C:\Users\auser\source\repos\myapp\myapp\docs\secured"/>
</appSettings>
<system.web>
  <authentication mode="Windows" />
  <identity impersonate="true"/>
  <authorization>
    <deny users="?" />
  </authorization>
</system.web>

I'm attempting to access files in two places. First, I index them (for now this runs from Application_Start):

var dirs = ConfigurationManager.AppSettings["documentFolder"].ToString().Split(',');

foreach (var dir in dirs)
{
    foreach (var file in Directory.GetFiles(dir, "*.pdf", SearchOption.TopDirectoryOnly))
    {
        try
        {
            FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read); // <-- Fails with "Access to the path 'C:\Users\auser\source\repos\myapp\myapp\docs\secured' is denied."
        }
        catch (Exception ex)
        {
            logger.Error("Failed to read file.", ex);
        }
    }
}

At a later point I attempt to check if the user has access:

protected void Button1_Click(object sender, EventArgs e)
{
    bool canSeeSecurityDocuments;
    try
    {
        System.Security.AccessControl.DirectorySecurity ds = Directory.GetAccessControl(ConfigurationManager.AppSettings["securityFolder"].ToString()); <-- Fails with "Attempted to perform an unauthorized operation."
        canSeeSecurityDocuments = true;
    }
    catch (Exception ex)
    {
        canSeeSecurityDocuments = false;
    }
}

From procmon:

Desired Access: Read Attributes, Read Control

Disposition: Open

Options: Open Reparse Point

Attributes: n/a

ShareMode: Read, Write, Delete

AllocationSize: n/a

Impersonating: mydomain\\myuserid <- redacted, but correct.

Based off research about integrated vs classic pipelines, I moved the GetFiles call to a different location and wrapped it in a WindowsImpersonationContext to see if that'd force impersonation, which it didn't. (From this SO answer ):

var current = System.Security.Principal.WindowsIdentity.GetCurrent();
logger.Debug(current.Name); <-- This is my identity

WindowsIdentity clientId = (WindowsIdentity)User.Identity;

using (WindowsImpersonationContext wic = clientId.Impersonate())
{
    current = System.Security.Principal.WindowsIdentity.GetCurrent();
    logger.Debug(current.Name); <-- This is still my identity

    // call to GetFiles, as above. Still fails.
}

current = System.Security.Principal.WindowsIdentity.GetCurrent();
logger.Debug(current.Name); <-- still me. Nothing seems to change.

Procmon事件选项卡 Procmon Process选项卡

The issue was that I was using the threadpool in order to do some background work (indexing files). It appears, according to this SO answer , that the threadpool doesn't carry over the credentials that were used to create it. I should have checked within the actual thread to see what the context was...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM