从基于 Sharepoint 声明的身份验证 Web 应用程序中的代码访问 Windows 共享

Posted

技术标签:

【中文标题】从基于 Sharepoint 声明的身份验证 Web 应用程序中的代码访问 Windows 共享【英文标题】:Accessing windows shares from the code in Sharepoint Claims Base Athentication Webapplication 【发布时间】:2012-11-29 09:34:59 【问题描述】:

我想通过代码访问另一台机器上的共享资源。我的环境是在声明身份验证模式下工作的 Sharepoint 2010 WebApplication。应用程序的 Windows 身份是 NT AUTHORITY\IUSR - 不是已登录的用户,因此要访问另一台机器上的网络共享资源,我需要执行模拟。由于我没有有效的 Windows 令牌来执行模拟,我需要使用对 Windows 令牌服务的声明,我已将其配置为能够被 NT AUTHORITY\IUSR 访问。该服务作为本地系统帐户运行。我可以使用以下代码从我用来执行模拟的服务中获取模拟级别 Windows 令牌:

using (wi = S4UClient.UpnLogon(upn))

    using(WindowsImpersonationContext wic2 = wi.Impersonate())
    
     //code to access windows shares
      
 

服务正在正确返回令牌并且模拟成功,当我使用以下代码返回当前登录用户的身份时:

WindowsIdentity.GetCurrent().Name;

我正在获取登录到共享点的用户的用户名。

问题是尝试访问网络资源时出现“拒绝访问”错误。问题很明显是因为通过 c2wts 进行的模拟,因为当我使用以下代码提供实际凭据(登录名和密码)来模拟用户时:

    [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;
    

我能够毫无问题地枚举服务器上的共享。

根据我在互联网上找到的信息,要正确配置服务以访问另一台服务器上的 sql 数据库,我需要在 Active Directory 中启用协议转换和约束委派,并将该约束设置为 mysql 服务。我仍然不确定在这种情况下如何启用委派,因为我想要实现的是能够访问任何机器上的任何共享,只要用户有权这样做。

总而言之,我想从基于 Sharepoint 声明的身份验证 WebApplication 中模拟用户以访问其他计算机上的网络共享,但即使使用 c2wts 进行艰难的模拟似乎也是成功的(检查当前用户名时返回正确的用户名)我不是能够访问另一台计算机上的资源。另一方面,当使用代码中直接提供的登录名和密码进行模拟时,一切正常,但这不是我的选择。

【问题讨论】:

【参考方案1】:

好的,我实际上设法解决了它。

我所做的是将我的 web 应用程序的 web.config 中的模拟设置为 false:

<identity impersonate="false" />

在这种情况下,我能够看到本地共享上的文件。要在其他计算机上启用访问权限,我必须为运行我的 Web 应用程序的帐户创建服务主体名称 (SPN)。

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

以及运行 webapplication 和 c2wts(c2wts 作为 LocalSystem)运行的计算机的 SPN

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

下一步是配置约束委派和协议转换,以便我们可以委派给另一台计算机上的文件共享,我们需要打开 Active Directory 用户和计算机工具并为 Web 应用程序帐户和计算机帐户配置委派c2wts 正在开发中。具体来说,我们需要:

选择我们感兴趣的账号,比如电脑账号, 右键, 选择属性, 选择委托选项卡, 选择“信任此计算机仅委派指定的服务”,然后 “使用任何身份验证协议”, 从我们要连接的计算机中添加“通用 Internet 文件系统 (cifs)”

我们需要为 webapp 帐户做同样的事情

设置值“信任此计算机以委派任何服务”将不起作用!

【讨论】:

以上是关于从基于 Sharepoint 声明的身份验证 Web 应用程序中的代码访问 Windows 共享的主要内容,如果未能解决你的问题,请参考以下文章

Sharepoint 区域身份验证不起作用

SharePoint 使用客户端证书为没有 Active Directory 帐户的用户声明身份验证

在声明身份验证的 SharePoint 2010 中托管的 WCF 服务中的模拟

Sharepoint 2010 自定义 Web 服务 - HTTP 请求未经客户端身份验证方案“Ntlm”授权

共享点身份验证。如何从 ADFS 获取 SharePoint cookie

如何从 sharepoint 2013 Web 服务和 Active Directory 对用户进行身份验证