Accessing windows shares from the code in Sharepoint Claims Base Athentication Webapplication

1.5k Views Asked by At

I want to access shared resources on the other machine from code. My environment is a Sharepoint 2010 WebApplication working in Claims Authentication mode. Application's Windows identity is NT AUTHORITY\IUSR - not the user that has logged in, so to access the net share resources on the other machine I need to perform impersonation. Since I have no valid windows token to perform impersonation I need to use Claims To Windows Token Service, which I have configured to be able to be accessed by NT AUTHORITY\IUSR. The service is running as Local System account. I am able to get the impersonation level windows token from the service which I am using to perform impersonation using following code:

using (wi = S4UClient.UpnLogon(upn))
{
    using(WindowsImpersonationContext wic2 = wi.Impersonate())
    {
     //code to access windows shares
    }  
} 

The service is properly returning the token and the impersonation is successful in a way that when I return the current loggedin user's identity using following code:

WindowsIdentity.GetCurrent().Name;

I am getting the username of the user that is logged in to sharepoint.

The problem is that there is an "access denied" error when trying to access the network resources. The problem is surly because of the impersonation via c2wts since when I am providing the actual credentials (login and password) to impersonate the user using following code:

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern Int32 LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, Int32 dwLogonType, Int32 dwLogonProvider, ref IntPtr phToken);

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern Int32 ImpersonateLoggedOnUser(IntPtr hToken);

private static IntPtr ImpersonateUser(string user, string domain, string password)
    {
        IntPtr lnToken = new IntPtr(0);
        Int32 TResult = LogonUser(user, domain, password, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_WINNT50, ref lnToken);

        if (TResult > 0)
        {
            ImpersonateLoggedOnUser(lnToken);
        }

        return lnToken;
    }

I am able to enumerate shares on the server without any problem.

From the information I found on the internet to properly configure the service to access the sql database on another server I need to enable protocol transition and constrained delegation in the Active Directory and set that constrain to the mysql service. Still I am not sure how to enable delegation in this case since what I am trying to achieve is to be able to access any share on any machine, if only the user has permissions to do it.

To sum things up, I want to impersonate the user from within Sharepoint Claims Based Authentication WebApplication to access net shares on other computers but even tough impersonation using c2wts seems to be successful(correct username returned when checking current username) I am not able to access the resources on the other computer. On the other hand when impersonating using login and password provided directly in the code everything works ok, but that is not an option for me.

1

There are 1 best solutions below

0
On

Ok I actually managed to solve it.

What I did was setting the impersonation in the web.config of my webapplication to false:

<identity impersonate="false" />

In that case I was able to see files on the local shares. To enable acccess in other computers I had to create Service Principal Name (SPN) for the account on which my webapplication was running.

SETSPN -A HTTP/ServerName myDomain\webAppAccountUserName
SETSPN -A HTTP/FQDNServerName myDomain\webAppAccountUserName

and SPN for the computer that webapplication and c2wts (c2wts is working as LocalSystem) was running

SETSPN -A HOST/ServerName ServerName 
SETSPN -A HOST/FQDNServerName ServerName 

Next step is to configure constrained delegation and protocol transitioning so we can delegate to the file share on the other computer to do that we need to open Active Directory Users And Computers Tool and configure delegation for the web application account and computer account that c2wts is working on. Specifically we need to:

  • select the account we are interested in, like computer account,
  • right click,
  • select properties,
  • select delegation tab,
  • select "Trust this computer for delegation to specified services only" and "Use any authentication protocol",
  • add "common internet file system (cifs)" from the computer we want to connect to

We need to do exactly the same thing for the webapp account

Setting the value "Trust this computer for delegation to any service" will not work!