4

I'm trying to use Impersonation and Delegation in an intranet ASP.Net web-app in order to pass authenticated users' credentials onto a File Server so it can write a file to a directory.

The web server and file server are two separate machines, but in the same domain, so Delegation is required.

I've done the following:

  • Set <authentication mode="Windows"/> and <identity impersonate="true"/> in my web-app's web.config.
  • Enabled Constrained Delegation from the web server to the file server's HOST service and CIFS (Common Internet File System, in Active Directory.
  • Enabled only Windows Authentication in the website, through IIS.

Apparently this should all work, but it doesn't. I am getting ACCESS DENIED when I try to create a folder on the File Server from the Web App.

All the web pages I've read seem to indicate that my setup should work. What am I missing?

Notes:

  • My username gets passed to the web server fine.
  • I am part of a group that has full rights to the folder that I am creating the folder in.
Kyle Johnson
  • 763
  • 1
  • 13
  • 31

5 Answers5

1

Most likely you are running into double hop issue with Kerberos authentication. There are 2 options that I know of.

  1. Setup your SPN for your site's identity.
  2. Turn off Kerberos in IIS and use NTLM only authentication.

I think the best option is option 1, but that depends on how much access you have on your network.

Here's the KB as it relates to IIS6.

Also post how your application pools are configured.

Eugene S.
  • 3,256
  • 1
  • 25
  • 36
0

Our ASP.NET project uses separate file server as well. We found out that a reliable way to do it is to open secondary connection via WNetAddConnection2A API call. Here's a basic implementation (VB.NET)

API declarations

<StructLayout(LayoutKind.Sequential)> Private Structure NETRESOURCE
    Public dwScope As Integer
    Public dwType As Integer
    Public dwDisplayType As Integer
    Public dwUsage As Integer
    <MarshalAs(UnmanagedType.LPStr)> Public lpLocalName As String
    <MarshalAs(UnmanagedType.LPStr)> Public lpRemoteName As String
    <MarshalAs(UnmanagedType.LPStr)> Public lpComment As String
    <MarshalAs(UnmanagedType.LPStr)> Public lpProvider As String
End Structure

<DllImport("mpr.dll")> _
Private Shared Function WNetAddConnection2A( _
<MarshalAs(UnmanagedType.LPArray)> ByVal lpNetResource As NETRESOURCE(), _
<MarshalAs(UnmanagedType.LPStr)> ByVal lpPassword As String, _
<MarshalAs(UnmanagedType.LPStr)> ByVal lpUserName As String, _
ByVal dwFlags As Integer) As Integer

End Function

<DllImport("mpr.dll")> _
Private Shared Function WNetCancelConnection2A( _
<MarshalAs(UnmanagedType.LPStr)> ByVal lpName As String, _
ByVal dwFlags As Integer, ByVal fForce As Integer) As Integer

End Function


Public Shared Sub WNetAddConnection2AEx(ByVal i_sPath As String, ByVal i_sPassword As String, ByVal i_sUserID As String)
    Dim nr(1) As NETRESOURCE
    nr(0).lpRemoteName = i_sPath
    nr(0).lpLocalName = ""
    nr(0).dwType = 1
    nr(0).dwDisplayType = 0
    nr(0).dwScope = 0
    nr(0).dwUsage = 0
    nr(0).lpComment = ""
    nr(0).lpProvider = ""
    Dim iErr As Integer = WNetAddConnection2A(nr, i_sPassword, i_sUserID, 0)
    If iErr > 0 Then Throw New Exception("Can not connect to share folder: " & i_sPath)
End Sub

Usage

WNetAddConnection2AEx("\\server\path", "password", "user_id")
''...
''perform your file operation here
''...
WNetCancelConnection2A("\\server\path", 0, -1)
Yuriy Galanter
  • 38,833
  • 15
  • 69
  • 136
0

Configure IIS for Delegation To turn on Integrated Windows authentication and impersonation for an ASP.NET-connected application, you have to configure Internet Information Services (IIS). To configure for Windows Authentication in IIS, follow these steps: Click Start, click Run, type inetmgr, and then click OK. Expand local computer, and then expand Web site. Right-click Default Web site, and then click Properties. Click the Directory Security tab, and then click Edit under Anonymous access and authentication control. Click to select the Integrated Windows authentication check box, and then click to clear the Anonymous access, Digest authentication for Windows domain server and Basic Authentication check boxes.

Samad
  • 71
  • 2
  • 10
0

Ok, I got it! I got an ASPX page to read files, write files, and create folders on a UNC path to another server. This was done on two Windows Server 2012 instances, running .Net Framework 4, using a generic Workgroup type network, no Domain authentication.

Here's what it took...

  1. Setup a user "FileShare" on both servers, with the same password.
  2. Add "FileShare" to group "IIS_IUSRS" on the IIS server, otherwise it won't be able to compile the site
  3. Give Read/Write/Modify permissions to "FileShare" on the physical folder of the destination server
  4. Share said folder over the network \\MyDestServer\MySharedFolder
  5. Web.config <authentication mode="Windows" />
  6. Web.config <identity impersonate="true" userName="FileShare" password="password"/>

Now use your code to write a file to the network folder, here's a sample I used.

    try
    {
        string strFile = "\\MYDestServer\MySharedFolder\Test.txt";
        if (!System.IO.File.Exists(strFile))
        {
            var stream = System.IO.File.CreateText(strFile);
            stream.WriteLine("This file was created on: " + DateTime.Now.ToString());
            stream.Close();
            stream.Dispose();
            litCreateFileTest.Text = "File Created<br/>" + strFile;
        }
        else
        {
            var inStream = System.IO.File.OpenText(strFile);
            string strContent = inStream.ReadToEnd();
            inStream.Close();
            inStream.Dispose();

            strContent += "modified on: " + DateTime.Now.ToString() + "\r\n";

            var outStream = System.IO.File.CreateText(strFile);
            outStream.Write(strContent);
            outStream.Close();
            outStream.Dispose();

            litCreateFileTest.Text = "File Updated<br/>" + strFile;
        }
    }
    catch (Exception ex)
    {
        litCreateFileTest.Text = "Error: " + ex.Message;
    }
Ty H.
  • 905
  • 8
  • 8
0

We went to Active Directory Users and Groups.

  1. Located the web server, right-clicked and selected Properties.
  2. On the Delegation tab we enabled delegation for any protocol.

This did not immediately work but we think this is what did it eventually.

I will verify with further testing when we move the application to our stage environment.

Kyle Johnson
  • 763
  • 1
  • 13
  • 31