C#之模拟AD用户请求Sharepoint网站

最近在用Sharepoint时,碰到一个奇怪的问题:针对协作站点和文档中心(Blog、Wiki、Meeting等不会出现这种情况),当系统账户凭据失效时,其他用户均无法登陆或者操作显示异常。也就是说,必须系统账户访问协作站点或者文档中心后,在一段时间内,其他用户才能登陆或者访问协作站点和文档中心。

站点结构如图:

image

相关异常日志如下:

 

w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Logging Correlation Data          xmnv    Medium      Name=Request (GET:http://10.10.10.112:80/aviage/SitePages/Home.aspx)    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             General                           72k8    High        Failed to determine the setup path of the list schema for feature {00BFEA71-E717-4E80-AA17-D0C71B360101}, list template 101.    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Logging Correlation Data          xmnv    Medium      Site=/    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Monitoring                        b4ly    High        Leaving Monitored Scope (PostResolveRequestCacheHandler). Execution Time=15.0540781021052    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             General                           72k8    High        Failed to determine the setup path of the list schema for feature {00BFEA71-C796-4402-9F2F-0EB9A6E71B18}, list template 119.    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             General                           xxph    High        Failed to get the Fields schema with 0x8107058A    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             General                           8sl1    High        DelegateControl: Exception thrown while adding control 'ASP._controltemplates_publishingconsole_ascx': Operation is not valid due to the current state of the object.    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             General                           72k8    High        Failed to determine the setup path of the list schema for feature {00BFEA71-E717-4E80-AA17-D0C71B360101}, list template 101.    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Web Parts                         7935    Information    http://10.10.10.112/aviage/SitePages/Home.aspx - An unexpected error has been encountered in this Web Part.  Type: Microsoft.SharePoint.WebPartPages.XsltListViewWebPart, Error: An error has occurred.    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             General                           72k8    High        Failed to determine the setup path of the list schema for feature {00BFEA71-C796-4402-9F2F-0EB9A6E71B18}, list template 119.    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             General                           xxph    High        Failed to get the Fields schema with 0x8107058A    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Runtime                           tkau    Unexpected    System.InvalidOperationException: Operation is not valid due to the current state of the object.    at Microsoft.SharePoint.SPUserToken.GetClaimsUserLoginName()     at Microsoft.SharePoint.SPSite.CopyUserToken(SPUserToken userToken)     at Microsoft.SharePoint.SPSite.SPSiteConstructor(SPFarm farm, Guid applicationId, Guid contentDatabaseId, Guid siteId, Guid siteSubscriptionId, SPUrlZone zone, Uri requestUri, String serverRelativeUrl, Boolean hostHeaderIsSiteName, SPUserToken userToken)     at Microsoft.SharePoint.SPSite..ctor(Guid id, SPFarm farm, SPUrlZone zone, SPUserToken userToken)     at Microsoft.SharePoint.SPSite..ctor(Guid id, SPFarm farm, SPUrlZone zone)     at Microsoft.SharePoint.SPFeatureManager.EnsureSiteAndWeb(SPUrlZone zone, Guid databaseid, Guid siteid, Guid webid, SPSite&...    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Runtime                           tkau    Unexpected    ... site, SPWeb& web)     at Microsoft.SharePoint.SPFeatureManager.<>c__DisplayClass19.<GetFeatureRootAndListSchemaPaths>b__18()     at Microsoft.SharePoint.SPSecurity.RunAsUser(SPUserToken userToken, Boolean bResetContext, WaitCallback code, Object param)     at Microsoft.SharePoint.SPFeatureManager.GetFeatureRootAndListSchemaPaths(Byte[]& userToken, Guid& tranLockerId, Int32 nZone, Guid databaseid, Guid siteid, Guid webid, Guid featid, Int32 ltid, String& sPathToFeatureRoot, String& sPathToSchemaXml)     at Microsoft.SharePoint.Library.SPRequestInternalClass.GetListItemDataWithCallback2(IListItemSqlClient pSqlClient, String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback,...    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Runtime                           tkau    Unexpected    ... ISPDataCallback pPagingPrevCallback, ISPDataCallback pFilterLinkCallback, ISPDataCallback pSchemaCallback, ISPDataCallback pRowCountCallback, Boolean& pbMaximalView)     at Microsoft.SharePoint.Library.SPRequest.GetListItemDataWithCallback2(IListItemSqlClient pSqlClient, String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pPagingPrevCallback, ISPDataCallback pFilterLinkCallback, ISPDataCallback pSchemaCallback, ISPDataCallback pRowCountCallback, Boolean& pbMaximalView)     at Microsoft.SharePoint.SPListItemCollection.EnsureListItemsData()     at Microsoft.SharePoint.SPListItemCollection.get_Count()     at Microsoft.SharePoint.SPList.GetItemById(Strin...    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Runtime                           tkau    Unexpected    ...g strId, Int32 id, String strRootFolder, Boolean cacheRowsetAndId, String strViewFields, Boolean bDatesInUtc)     at Microsoft.SharePoint.SPContext.get_Item()     at Microsoft.SharePoint.SPContext.get_Fields()     at Microsoft.SharePoint.WebControls.FieldMetadata.get_Field()     at Microsoft.SharePoint.WebControls.FormField.CreateChildControls()     at System.Web.UI.Control.EnsureChildControls()     at Microsoft.SharePoint.WebPartPages.WikiEditPage.OnLoad(EventArgs e)     at System.Web.UI.Control.LoadRecursive()     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)    7b7ff55b-fbdb-442c-96df-10cd59c5691a
w3wp.exe (0x15B8)    0x1048    SharePoint Foundation             Monitoring                        b4ly    Medium      Leaving Monitored Scope (Request (GET:http://10.10.10.112:80/aviage/SitePages/Home.aspx)). Execution Time=36.9820046961276    7b7ff55b-fbdb-442c-96df-10cd59c5691a

关键异常如下:

at Microsoft.SharePoint.SPUserToken.GetClaimsUserLoginName()     at Microsoft.SharePoint.SPSite.CopyUserToken(SPUserToken userToken)     at Microsoft.SharePoint.SPSite.SPSiteConstructor(SPFarm farm, Guid applicationId, Guid contentDatabaseId, Guid siteId, Guid siteSubscriptionId, SPUrlZone zone, Uri requestUri, String serverRelativeUrl, Boolean hostHeaderIsSiteName, SPUserToken userToken)

初步诊断发现,是同时集成Windows验证和Form验证导致的,因为建设同样架构的站点,不集成form验证则不会出现该问题。根据日志搜索,折腾半天,发现老外遇到过,但是无解决方案,不知道是否为SharePoint的BUG,因为Form验证仔细检查过,并不存在问题,那么只能自己想办法了。于是诞生了使用C#模拟系统账户登陆来请求相关页面了。关键代码如下:

private static void RequestUrl(string url, int i)
{
    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        //下面三行代码,启用任意一行都是可以的。
        //request.UseDefaultCredentials = true;
        //request.Credentials = CredentialCache.DefaultCredentials;
        request.ContentType = "application/x-www-form-urlencoded";
        request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6.4; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
        //request.Credentials = CredentialCache.DefaultNetworkCredentials;
        var cre = new NetworkCredential("sharepoint", "Sharepointadmin", "域名");
        //request.Credentials = cre;
        request.Credentials = cre.GetCredential(new Uri(url), String.Empty);
        request.Accept = "*/*";
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {
                var content = sr.ReadToEnd().ToString();
                var path = Path.Combine(Application.StartupPath, "WebPages");
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                path = Path.Combine(path, string.Format("{0}.txt", i));
                File.WriteAllText(path, content, Encoding.UTF8);
            }
        }
    }
    catch (WebException wex)
    {
        NLog.LogManager.GetCurrentClassLogger().ErrorException("请求异常", wex);
    }
}

代码是比较简单的,但也折腾了一会,因为关于模拟AD验证的关键字搜到的都是做AD验证而不是模拟AD请求验证,根据MSDN的说明,下面三行代码应该都是可用的:

//request.UseDefaultCredentials = true;
//request.Credentials = CredentialCache.DefaultCredentials;
//request.Credentials = CredentialCache.DefaultNetworkCredentials;

因为都是默认使用当前Windows用户进行请求,可是放服务器上运行发现是拒绝访问的。几经折腾,才发现只有上面的方式才能实现请求。

模拟请求的实现了,那么只要每隔一段时间模拟系统账户请求相关页面,那么问题就解决了,而且页面显示的速度也会快很多。

最后,如果有同学解决了上面那个SharePoint问题,请通知我,毕竟我这种方式并不是很“光彩”。

posted @ 2012-09-24 23:41  雪雁  阅读(2906)  评论(2编辑  收藏  举报