"指定的登录会话不存在。它可能已经被终止了。”尝试使用 WindowsIdentity.Impersonate 复制文件时

发布于 2024-08-03 08:42:49 字数 586 浏览 1 评论 0 原文

我正在尝试将文件从共享点复制到 unc 路径。我使用以下代码:

 var id = new WindowsIdentity("[email protected]");
 var p = new WindowsPrincipal(id);
 var wic = id.Impersonate();
 File.Move(oldName, newName);
 wic.Undo();

oldname is C:\test.txt newName 是 \\server\folder\test.txt

我收到错误

A specified logon session does not exist. It may already have been terminated.

如何删除此错误或使用共享点将文件从 A 复制到 B(UNC 路径)。

I am trying to copy a file from sharepoint to a unc path. I am using the following code:

 var id = new WindowsIdentity("[email protected]");
 var p = new WindowsPrincipal(id);
 var wic = id.Impersonate();
 File.Move(oldName, newName);
 wic.Undo();

oldname is C:\test.txt
newName is \\server\folder\test.txt

I am getting the error

A specified logon session does not exist. It may already have been terminated.

How do I go about removing this error OR copy a file from A to B(UNC path) using sharepoint.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南七夏 2024-08-10 08:42:49

以下类将允许您通过用户名和密码访问 SMB 共享。在 Windows 到 Windows 和 Windows 到 UNIX 环境中将文件复制到网络共享时,我一直使用它。这样做的好处是您不需要进行用户身份验证。本质上,您可以使用仅目标计算机本地的凭据。

class WNetConnection : IDisposable
{
    public readonly string RemoteShare;

    public WNetConnection( string remoteHost, string remoteUser, string remotePassword )
    {
        Uri loc;
        if( !Uri.TryCreate( remoteHost, UriKind.Absolute, out loc ) || loc.IsUnc == false )
            throw new ApplicationException( "Not a valid UNC path: " + remoteHost );

        string auth = loc.Host;
        string[] segments = loc.Segments;

        // expected format is '\\machine\share'
        this.RemoteShare = String.Format( @"\\{0}\{1}", auth, segments[1].Trim( '\\', '/' ) );

        this.Connect( remoteUser, remotePassword );
    }

    ~WNetConnection()
    {
        Disconnect();
    }

    public void Dispose()
    {
        Disconnect();
        GC.SuppressFinalize( this );
    }

    #region Win32 API...

    [StructLayout( LayoutKind.Sequential )]
    internal struct NETRESOURCE
    {
        public int dwScope;
        public int dwType;
        public int dwDisplayType;
        public int dwUsage;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpLocalName;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpRemoteName;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpComment;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpProvider;
    }

    [DllImport( "mpr.dll", EntryPoint = "WNetAddConnection2W", CharSet = System.Runtime.InteropServices.CharSet.Unicode )]
    private static extern int WNetAddConnection2( ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, Int32 dwFlags );

    [DllImport( "mpr.dll", EntryPoint = "WNetCancelConnectionW", CharSet = System.Runtime.InteropServices.CharSet.Unicode )]
    private static extern int WNetCancelConnection( string lpRemoteName, bool bForce );

    private const int RESOURCETYPE_ANY = 0x00000000;
    private const int RESOURCETYPE_DISK = 0x00000001;
    private const int CONNECT_INTERACTIVE = 0x00000008;
    private const int CONNECT_PROMPT = 0x00000010;
    private const int NO_ERROR = 0;

    void Connect( string remoteUser, string remotePassword )
    {
        NETRESOURCE ConnInf = new NETRESOURCE();
        ConnInf.dwScope = 0;
        ConnInf.dwType = RESOURCETYPE_DISK;
        ConnInf.dwDisplayType = 0;
        ConnInf.dwUsage = 0;
        ConnInf.lpRemoteName = this.RemoteShare;
        ConnInf.lpLocalName = null;
        ConnInf.lpComment = null;
        ConnInf.lpProvider = null;

        // user must be qualified 'authority\user'
        if( remoteUser.IndexOf( '\\' ) < 0 )
            remoteUser = String.Format( @"{0}\{1}", new Uri(RemoteShare).Host, remoteUser );

        int dwResult = WNetAddConnection2( ref ConnInf, remotePassword, remoteUser, 0 );
        if( NO_ERROR != dwResult )
            throw new Win32Exception( dwResult );
    }

    void Disconnect()
    {
        int dwResult = WNetCancelConnection( this.RemoteShare, true );
        if( NO_ERROR != dwResult )
            throw new Win32Exception( dwResult );
    }

    #endregion
}

The following class will allow you to access SMB shares via a user-name and password. I use it all the time when copying files to network shares in both windows-to-windows and windows-to-unix environments. The benefit here is that you do not need to be authenticate as the user. In essence, you can use credentials that are local only to the target machine.

class WNetConnection : IDisposable
{
    public readonly string RemoteShare;

    public WNetConnection( string remoteHost, string remoteUser, string remotePassword )
    {
        Uri loc;
        if( !Uri.TryCreate( remoteHost, UriKind.Absolute, out loc ) || loc.IsUnc == false )
            throw new ApplicationException( "Not a valid UNC path: " + remoteHost );

        string auth = loc.Host;
        string[] segments = loc.Segments;

        // expected format is '\\machine\share'
        this.RemoteShare = String.Format( @"\\{0}\{1}", auth, segments[1].Trim( '\\', '/' ) );

        this.Connect( remoteUser, remotePassword );
    }

    ~WNetConnection()
    {
        Disconnect();
    }

    public void Dispose()
    {
        Disconnect();
        GC.SuppressFinalize( this );
    }

    #region Win32 API...

    [StructLayout( LayoutKind.Sequential )]
    internal struct NETRESOURCE
    {
        public int dwScope;
        public int dwType;
        public int dwDisplayType;
        public int dwUsage;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpLocalName;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpRemoteName;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpComment;
        [MarshalAs( UnmanagedType.LPWStr )]
        public string lpProvider;
    }

    [DllImport( "mpr.dll", EntryPoint = "WNetAddConnection2W", CharSet = System.Runtime.InteropServices.CharSet.Unicode )]
    private static extern int WNetAddConnection2( ref NETRESOURCE lpNetResource, string lpPassword, string lpUsername, Int32 dwFlags );

    [DllImport( "mpr.dll", EntryPoint = "WNetCancelConnectionW", CharSet = System.Runtime.InteropServices.CharSet.Unicode )]
    private static extern int WNetCancelConnection( string lpRemoteName, bool bForce );

    private const int RESOURCETYPE_ANY = 0x00000000;
    private const int RESOURCETYPE_DISK = 0x00000001;
    private const int CONNECT_INTERACTIVE = 0x00000008;
    private const int CONNECT_PROMPT = 0x00000010;
    private const int NO_ERROR = 0;

    void Connect( string remoteUser, string remotePassword )
    {
        NETRESOURCE ConnInf = new NETRESOURCE();
        ConnInf.dwScope = 0;
        ConnInf.dwType = RESOURCETYPE_DISK;
        ConnInf.dwDisplayType = 0;
        ConnInf.dwUsage = 0;
        ConnInf.lpRemoteName = this.RemoteShare;
        ConnInf.lpLocalName = null;
        ConnInf.lpComment = null;
        ConnInf.lpProvider = null;

        // user must be qualified 'authority\user'
        if( remoteUser.IndexOf( '\\' ) < 0 )
            remoteUser = String.Format( @"{0}\{1}", new Uri(RemoteShare).Host, remoteUser );

        int dwResult = WNetAddConnection2( ref ConnInf, remotePassword, remoteUser, 0 );
        if( NO_ERROR != dwResult )
            throw new Win32Exception( dwResult );
    }

    void Disconnect()
    {
        int dwResult = WNetCancelConnection( this.RemoteShare, true );
        if( NO_ERROR != dwResult )
            throw new Win32Exception( dwResult );
    }

    #endregion
}
神回复 2024-08-10 08:42:49

您实际上并没有获得要模拟的登录令牌。您需要调用 LogonUser API 来获取有效的登录令牌,您可以使用该令牌来模拟该用户。

请参阅此博客条目 例如,C# 中模拟 Windows 用户的代码。您还可以查看这篇知识库文章,其中还包含 C# 代码(以及针对以下问题的重复令牌调用) .net 1.0)

You are not actually getting a logon token to impersonate. You need to call the LogonUser API to get a valid logon token, which you can use to impersonate that user.

See this blog entry for example code in c# on impersonating a windows user. You can also see this KB article that also contains c# code (and a duplicatetoken call for issues with .net 1.0)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文