简体   繁体   中英

Web service execute on remote computer

I'm using asmx web service to lock a folder on remote computer!

When I run web service on local machine everything working fine, but when I run it on remote computer nothing happen, folder on remote computer stay unlock!

I supose that I need to set security permission for this web service on remote computer, but i don't know where!

So, what I need to enable executing this service on remote computer?

What credentials is the remote asmx running under? Does it have the rights to do operations on the file system outside of its own folder structure?

I suspect it is permissions, does the network service have read/write access to folder?

Maybe you can try identity impersonate.

<system.web>
<identity impersonate="true" userName="WindowsDomain\YourUserName" password="YourPassword" />
</system.web> 

EDIT I would begin by checking that the folder on the server has write permissions for the Network Service. If the folder security can not be changed then use the identity impersonate in the web config and map it a user on the server.

EDit 2 Do you get any kind of error thrown when the code tries to lock the folder?

This is the function that remove user allow permission on certain folder:

Public Function RemoveAllowPermission(ByVal filePath As String, ByVal username As String, ByVal power As String) 

        Dim dirinfo As DirectoryInfo = New DirectoryInfo(filePath)

        Dim dirsecurity As DirectorySecurity = dirinfo.GetAccessControl()
        dirsecurity.SetAccessRuleProtection(True, True)
        Select Case power

            Case "FullControl"

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.FullControl, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow))

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.FullControl, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow))

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.FullControl, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow))

            Case "ReadOnly"

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.Read, AccessControlType.Allow))

            Case "Write"

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.Write, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow))

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.Write, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow))

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.Write, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow))

            Case "Modify"

                dirsecurity.RemoveAccessRuleAll(New FileSystemAccessRule(username, FileSystemRights.Modify, AccessControlType.Allow))

        End Select

        dirinfo.SetAccessControl(dirsecurity)

    End function

In next function i call RemoveAllowPermission function:

 <WebMethod()> _
    Public Function ChangePermission()
        Dim file As String = "C:\Pictures"
        Dim fs As FileSecurity = System.IO.File.GetAccessControl(file)
        Dim owner As NTAccount = CType(fs.GetOwner(GetType(NTAccount)), NTAccount)

        Dim usergroup As AuthorizationRuleCollection = fs.GetAccessRules(True, True, (GetType(System.Security.Principal.NTAccount)))
        Try
            For Each Rule As FileSystemAccessRule In usergroup
                RemoveAllowPermission(file, Rule.IdentityReference.Value, "FullControl")
              Next
        Catch ex As Exception
Return ("Error")
        End Try
    End Sub
Return 0
End Class

So when I run service on remote computer my ChangePermission function catch exception and return exception message Error!

As it is ASMX, I think that it falls for impersonation rules of ASP.NET. As there is no login function programmatically you should use the unmanaged api.

Let's say you need to do something in an impersonation context (under the remote's computer user account that has access at where you want).

Impersonation.Execute(myEntity.NasUser, myEntity.NasPassword, () =>    
{     
//Copy File to UNC Path for example
   File.Copy(sourceFile, Path.Combine(myEntity.UploadPath, Path.GetFileName(sourceFile)), true);     
});

Import the unmanaged api:

    [DllImport("advapi32.dll", SetLastError = true)]     
    public static extern bool LogonUser(     
        string lpszUsername,     
        string lpszDomain,     
        string lpszPassword,     
        int dwLogonType,     
        int dwLogonProvider,     
        out IntPtr phToken     
        );    
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]     
    public extern static bool CloseHandle(IntPtr handle);     

The aforementioned execute could be something like that:

public static void Execute(string userName, string domain, string password, Action action)    
    {     
        try     
        {     
            bool bImpersonated = LogonUser(     
                userName,     
                domain,     
                password,     
                logon32LogonInteractive,     
                logon32ProviderDefault,     
                out tokenHandle);     
            if (bImpersonated == false)     
            {     
                throw new Win32Exception(Marshal.GetLastWin32Error());     
            }     
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);     
            impersonatedUser = newId.Impersonate();     
            action();     
        }     
        catch (Exception ex)     
        {     
            throw ex;     
        }     
        finally     
        {     
            if (impersonation != null)     
                impersonation.Dispose();     
        }     
    }

You should not forget to undo the impersonation and return to the previous windowscredentials state:

public void Dispose()    
{     
    // Stop impersonating the user.     
    if (impersonatedUser != null)     
        impersonatedUser.Undo();     
    // close handle     
    if (tokenHandle != IntPtr.Zero)     
        CloseHandle(tokenHandle);     
}

Well you could always run the Application Pool of the web service as with an Administrator account! Not advised to do that in production but if it works at least you have a starting point. Good luck.

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