我花了几个小时研究一个来自.NET Web服务请求AD信息用户权限的Web方法的奇怪“bug”。
好消息是我修复了这个错误,但我理解为什么修正是有效的。
包含错误的网络方法如下:
public bool ValidateTask(string originatingUser)
{
SPUserToken userToken = null;
// get the System account for impersonation
string userToken = site.SystemAccount.UserToken;
using (SPSite rootSite = new SPSite(site.ID, userToken))
{
using (SPWeb web = rootSite.OpenWeb())
{
// get the domain name of the application pool of the web app
string servicesDomain =
StringUtilities.GetDomain(site.WebApplication.ApplicationPool.ManagedAccount.Username);
// get the domain name of the user
string accountsDomain = StringUtilities.GetDomain(originatingUser);
PrincipalContext ServicesDomainContext =
new PrincipalContext(ContextType.Domain, servicesDomain);
PrincipalContext AccountsDomainContext =
new PrincipalContext(ContextType.Domain, accountsDomain);
// COMException when the FindByIdentity is called because
// AccountsDomainContext.connectedServer throw exception
using (UserPrincipal usr =
UserPrincipal.FindByIdentity(AccountsDomainContext, IdentityType.SamAccountName, originatingUser))
{
// get user groups memberships
}
}
// check groups memberships and return the true or false
}
}
带有更正的网络方法如下:
public bool ValidateTask(string originatingUser)
{
SPSecurity.RunWithElevatedPrivileges(
delegate ()
{
...
using (SPSite rootSite = new SPSite(site.ID))
{
using (SPWeb web = rootSite.OpenWeb())
{
// get the domain name of the application pool of the web app
string servicesDomain =
StringUtilities.GetDomain(site.WebApplication.ApplicationPool.ManagedAccount.Username);
// get the domain name of the user
string accountsDomain = StringUtilities.GetDomain(originatingUser);
PrincipalContext ServicesDomainContext =
new PrincipalContext(ContextType.Domain, servicesDomain);
PrincipalContext AccountsDomainContext =
new PrincipalContext(ContextType.Domain, accountsDomain);
using (UserPrincipal usr =
UserPrincipal.FindByIdentity(AccountsDomainContext, IdentityType.SamAccountName, originatingUser))
{
// get user groups memberships
}
}
}
// check groups memberships and return the true or false
}
); // end of delegate method
}
=============================================== ============================
在sharepoint中,我认为Impersonation和RunWithElevatedPrivilege会产生相同的结果。 所以我的问题是:
1-那么为什么RunWithElevatedPrivilege有效?
2-当我们提升WebMethod上下文中的权限时,凭据是什么?这是SharePoint Web服务根目录的标识池帐户?
3-我可以追踪两种方法的凭证吗?
答案 0 :(得分:1)
RunWithElevatedPrivileges在新线程中运行代码。此新线程在当前应用程序池的帐户下运行。如果你打电话,例如在http://localhost/_vti_bin/yourservice下,应用程序池是Web应用程序在端口80上的应用程序。 使用带有用户令牌的新SPSite仅在已定义用户的上下文中打开SPSite,并且不会启动新线程。 您可以通过调用WindowsIdentity.Current
来跟踪当前用户