终于解决了访问被拒绝的问题。正如我在上一封电子邮件中提到的那样,问题是由于对我的应用程序池身份的权限不足。
- Central Admin 在不同的应用程序池标识下运行
- Web 应用程序在不同的应用程序池标识下运行。
我的工作流使用 ElevatedPrevilages 来配置网站集,并且它曾经从数据库中获取拒绝访问,因为它没有修改 SharePoint_Config 数据库的权限。
解决方法 为了解决这个问题,我必须模拟 Central Admin 的应用程序池身份。这是模拟 Central Admin 应用程序池用户所需的方法。
#region Application Pool Identity Impersonate
protected static WindowsIdentity CreateIdentity(string User, string Domain, string Password)
{
// The Windows NT user token.
IntPtr tokenHandle = new IntPtr(0);
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_NETWORK = 3;
tokenHandle = IntPtr.Zero;
// Call LogonUser to obtain a handle to an access token.
int returnValue = LogonUser(User, Domain, Password,LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,out tokenHandle);
//Check if the logon user method succeeded
if (returnValue <= 0)
{
int ret = Marshal.GetLastWin32Error();
throw new Exception("LogonUser failed with error code: " + ret);
}
//System.Diagnostics.Debug.WriteLine("Created user token: " + tokenHandle);
//The WindowsIdentity class makes a new copy of the token.
//It also handles calling CloseHandle for the copy.
WindowsIdentity id = new WindowsIdentity(tokenHandle);
CloseHandle(tokenHandle);
return id;
}
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken
);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int ImpersonateLoggedOnUser(
IntPtr hToken
);
[DllImport("advapi32.dll", SetLastError = true)]
static extern int RevertToSelf();
[DllImport("kernel32.dll", SetLastError = true)]
static extern int CloseHandle(IntPtr hObject);
#endregion
然后我创建网站集的代码如下所示:-
//Impersonate the logged in user, ApplicationUser, LoginDomain and Password are exposed as property of the class.
WindowsImpersonationContext wiContext = CreateIdentity(this.ApplicationPoolUser, this.LoginDomain, this.SystemPassword).Impersonate();
//Provision new site collection and update the property for new site collection url.
using (SPSite newSiteCollection = spSiteColl.Add(SUGGESTEDURL, TITLE, DESC, LCID, WEBTEMPLATE, PRIMARYOWNER.LoginName, PRIMARYOWNER.Name, PRIMARYOWNER.Email, SECONDARYOWNER.LoginName, SECONDARYOWNER.Name, SECONDARYOWNER.Email))
{
this.SUGGESTEDURL = newSiteCollection.Url;
}
//Reset the impersonation.
wiContext.Undo();