Partager via


使用 SharePoint 2010 中的用戶端 OM 和 Web 服務從多個驗證網站擷取資料

英文原文已於 2011 年 4 月 2 日星期六發佈

光是本文的主題就有夠繞口,不過大概可以猜得出來我們今天會談到的內容。 本文將會解決長久以來困擾著其他人和我自己的問題。 我最近才開始四處詢問,然後因緣際會之下收到某人的電子郵件,對方剛收到有關如何解決這個問題的資訊。

 

我只講這個案例最常見的部分,因為它們可能會多了許多曲解。 案例的問題是,從使用多個驗證提供者的 SharePoint 網站擷取資料;在這個案例中,假設一個是 Windows 宣告,其他則是別的,例如可能是表單型驗證或 SAML 驗證。 您經常想要擷取來自使用用戶端 OM 或 SharePoint Web 服務這類網站的資料,但卻是使用 Windows 驗證。 到目前為止的問題一直出在,即使您在要求上設定 Windows 驗證,在要求資料時仍會收到「拒絕存取」。

 

這個問題的根本解決方案是,如果您想要以程式設計方式存取搭配使用多個驗證提供者與一組 Windows 認證的 SharePoint 網站,您必須在要求中新增其他標頭。 標頭名稱必須是 X-FORMS_BASED_AUTH_ACCEPTED,值必須是 “f”。 就這兩個常見案例而言,新增這個標頭還蠻簡單的,所以,本章其餘部分將說明如何使用一些範例程式碼進行新增。

 

如果您要使用用戶端 OM,必須為 ExecutingWebRequest 事件新增事件處理常式。 下列是範例程式碼:

 

//create the client context

ClientContext ctx = new ClientContext(MixedUrlTxt.Text);

//configure the handler that will add the header

ctx.ExecutingWebRequest +=

new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);

//set windows creds

ctx.AuthenticationMode = ClientAuthenticationMode.Default;

ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;

//get the web

Web w = ctx.Web;

//LOAD LISTS WITH ALL PROPERTIES

var lists = ctx.LoadQuery(w.Lists);

//execute the query

ctx.ExecuteQuery();

//enumerate the results

foreach (List theList in lists)

{

//do something with each list

}

 

而這裡是神奇之處:

 

void ctx_MixedAuthRequest(object sender, WebRequestEventArgs e)

{

try

{

              //add the header that tells SharePoint to use Windows Auth

              e.WebRequestExecutor.RequestHeaders.Add(

"X-FORMS_BASED_AUTH_ACCEPTED", "f");

       }

       catch (Exception ex)

       {

              MessageBox.Show("Error setting auth header: " + ex.Message);

       }

}

 

就是這些了;其實相當簡單且顯而易見。 使用標準 Web 服務參考執行相同的作業會有點不同。 若要開始,我們將帶領您完成在 SharePoint 網站中新增標準樣式 Web 參考到 Visual Studio 2010 中的專案:

1. 以滑鼠右鍵按一下 [服務參考] 節點,並選取 [加入服務參考]。

2. 按一下對話方塊底端的 [進階] 按鈕。

3. 按一下下一個對話方塊底端的 [加入 Web 參考] 按鈕。

4. 在 URL 編輯方塊中輸入您要使用的 Web 服務的 URL,例如,若要加入位於 https://foo 網站中清單 Web 服務的參考,我會輸入: https://foo/_vti_bin/lists.asmx。

5. 點擊 Enter 或按一下綠色箭號按鈕以尋找 Web 服務參考,然後在 Web 參考名稱編輯方塊中輸入您的 Web 服務參考的名稱,並且按一下 [加入參考] 按鈕。

 

現在應該會建立您的參考和 Proxy 類別,但是您必須新增其他部分類別,才能將標頭新增到您的 Web 服務要求。 開始時將新類別加入到您的專案,然後就能隨意呼叫它。 由於您只想要新增一些額外的行為,例如新增標頭到要求,您可讓它成為部分類別。 也就是說,您必須複製為 Web 參考所建立的 Proxy 中使用的命名空間和類別名稱。下列是執行步驟:

 

1. 按一下 Visual Studio [方案總管] 視窗中的 [顯示所有檔案] 按鈕。

2. 按一下您的 Web 服務參考旁邊的加號,展開檔案。

3. 按一下 Reference.map 檔案旁邊的加號,展開檔案。

4. 按兩下 Reference.cs 檔案,開啟檔案。

5. 將命名空間複製並貼到您的類別。

6. 複製類別名稱,包括繼承,然後貼到您的類別,做為類別名稱。 Web 服務參考類別已經是部分類別,所以您不需要做任何變更。

 

下列範例是我的 Web 服務參考的 Reference.cs 類別:

namespace ClientOmAuth.listsWS {

    using System;

    using System.Web.Services;

    using System.Diagnostics;

    using System.Web.Services.Protocols;

    using System.ComponentModel;

    using System.Xml.Serialization;

   

   

    /// <remarks/>

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.1")]

    [System.Diagnostics.DebuggerStepThroughAttribute()]

    [System.ComponentModel.DesignerCategoryAttribute("code")]

    [System.Web.Services.WebServiceBindingAttribute(Name="ListsSoap", Namespace="https://schemas.microsoft.com/sharepoint/soap/")]

    public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol {

而這裡是貼入我所建立類別的部分:

namespace ClientOmAuth.listsWS

{

       public partial class Lists : System.Web.Services.Protocols.SoapHttpClientProtocol

       {

       }

}

您會發現命名空間和類別名稱都相符,而且兩個類別都繼承自相同基底類型。

 

現在,您必須覆寫 GetWebRequest 方法才能新增標頭。 只要將這段程式碼加入您的部分類別就能達到:

protected override System.Net.WebRequest GetWebRequest(Uri uri)

{

       System.Net.WebRequest wr = null;

       try

       {

              wr = base.GetWebRequest(uri);

              wr.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");

       }

       catch (Exception ex)

       {

              //some error handling here

       }

                          

       return wr;

}

 

進行編碼以透過 Web 服務擷取資料,現在與您在任何 Windows 驗證 SharePoint 網站進行的方式完全相同:

 

//create the web service proxy and configure it use my Windows credentials

listsWS.Lists lws = new listsWS.Lists();

lws.UseDefaultCredentials = true;

//get the collection of lists

XmlNode xLists = lws.GetListCollection();

//enumerate results

foreach (XmlNode xList in xLists.ChildNodes)

{

//do something with each List

}

就是這些了。 您也可以使用我在下列網站所述的技術,套用這項資訊以透過 REST 擷取資料: https://blogs.technet.com/b/speschka/archive/2010/09/25/retrieving-rest-data-in-a-claims-based-auth-site-in-sharepoint-2010.aspx (可能為英文網頁)

 

這是翻譯後的部落格文章。英文原文請參閱 Retrieving Data from a Multi Auth Site Using the Client OM and Web Services in SharePoint 2010