在 SharePoint 2013 設定伺服器陣列間的 oAuth 信任
英文原文已於 2012 年 7 月 23 日星期一發佈
有個名詞您可能會很常在 SharePoint 2013 聽到,我之後應該也會一直提到它,它就是 oAuth。在 SharePoint 2013,我們用 oAuth 在兩個應用程式間建立信任,目的是為了建立主體 (使用者或應用程式) 的識別。使用 SharePoint 時,在 SharePoint 和其他程式 (例如 Exchange 和 Lync) 之間,您會用到 oAuth 信任 (如果 ACS 或應用程式開發人員使用的是雲端應用程式模型),或甚至是在兩個不同的 SharePoint 伺服器陣列之間也會用到,像是 [搜尋] 的遠端 SharePoint 索引功能。
oAuth 不提供驗證;您還是要用您的 New-SPTrustedIdentityTokenIssuer 向您的識別提供者建立信任。我們給 oAuth 信任一個名稱非常相似的新 Cmdlet,叫做 New-SPTrustedSecurityTokenIssuer。當我們與安全性權杖簽發者建立這一類的信任,我們把它稱為 S2S 信任,意思是「伺服器對伺服器」。請記住這個縮寫,因為接下來您會經常在 SharePoint 2013 看到它。在這篇文章中,我會談談一些建立這個信任所需要的個別項目。
首先值得一提的是,很多需要 S2S 信任的功能都會自行建立這個信任。他們可能透過功能啟動,也或者功能團隊會提供 PowerShell 指令碼或 Cmdlet 讓您執行,您開啟功能時即會建立信任。不過,有時候您必須自行建立,這正是這篇文章要討論的。
首先,您要解決的第一個問題是,要不要使用 SSL。事實是,在使用 SharePoint 2013 的大部分情況下,您或許應該使用 SSL。我這麼說是因為在 SharePoint 2013,有很多情況都會用到 oAuth,當您這麼做的時候,您是使用存取權杖在傳送 Cookie。存取權杖就像是一把鑰匙,打開資料大門的鎖。存取權杖由憑證簽署,因此不會被自行建立存取權杖的使用者欺騙,但您不會希望它以純文字的形式滿天飛,因為理論上,某人可以取得 Cookie,並且在 Cookie 有效期限內重新執行存取權限。SSL 可保護您免於 Cookie 重新執行攻擊,基於相同的理由,您會在表單型驗證網站以相同的方式使用 SSL。話雖這麼說,您還是會想透過 HTTP 執行網站 – 因為您身處於測試環境、您正在建立開發環境、您完全在內部網路執行,覺得沒有風險等等原因。我無意評論 – 我只是解釋原因。J
在設定 SharePoint 的 Security Token Service (STS) 時,如果您未使用 SSL,有些設定可能需要調整。您可以從這個 Cmdlet:Get-SPSecurityTokenServiceConfig 取得所有的 STS 設定。要建立信任有兩種方式 – 一個是使用憑證,一個是使用所有 SharePoint 伺服器陣列都有的新 oAuth 中繼資料端點。使用中繼資料端點是最簡單的方式,但如果中繼資料端點未受 SSL 安全保護,那麼您必須將 SharePoint STS 的 AllowMetadataOverHttp 屬性設定為 True。如果您不以 SSL 執行 Web 應用程式,您也必須將 AllowOAuthOverHttp 屬性設定為 True。以下 PowerShell 示範如何設定這些屬性:
$c = Get-SPSecurityTokenServiceConfig
$c.AllowMetadataOverHttp = $true
$c.AllowOAuthOverHttp= $true
$c.Update()
STS 都按照要求設定後,我們就可以看看如何在各伺服器陣列間建立信任。就像前面說過的,所有的 SharePoint 伺服器陣列都有一個中繼資料端點,現在中繼資料端點用於提供資訊以及提供簽署存取權杖的憑證。中繼資料端點位於 /_layouts/15/metadata/json/1。如果您實際在瀏覽器試著導覽至此位置,會出現提示要您儲存,您可以實際操作驗證是否真的如此。如果您用記事本開啟,您會發現它只是個 JSON 裝載。裡面包含 STS 的名稱識別碼 (它稱之為「簽發者」),還有序列版的權杖簽署憑證 (它將此稱為 x509certificate 金鑰的「值」)。如果您再進一步細看這份資料,您會發現事實上簽發者就是 servicename + “@” + realm 的值。它也會與 STS 上的 NameIdentifier 屬性相符;這個資訊非常重要,至於原因容後再述。
在這個例子中,讓我們假設 FARM_B 需要信任來自 FARM_A 的呼叫,因為 FARM_A 要用 FARM_B 做為遠端 SharePoint 索引。另外,我們假設 FARM_A 在 https://FARM_A 有 Web 應用程式。要建立信任,我們要像這樣在 FARM_B 的伺服器執行 New-SPTrustedSecurityTokenIssuer Cmdlet (我會在之後的文章解釋我為什麼用 “$i = “):
$i = New-SPTrustedSecurityTokenIssuer -Name FARM_A -Description "FARM_A description" -IsTrustBroker:$false -MetadataEndPoint "https://FARM_A/_layouts/15/metadata/json/1"
現在,我們假設您要用僅限服務的伺服器陣列設定信任。您不想只為了建立信任,就要建立 Web 應用程式、網站集合和 SSL 憑證。所以,我們有第二個方法讓您可用 New-SPTrustedSecurityTokenIssuer Cmdlet 建立信任。以第二種方式,您可以只提供權杖簽署憑證和名稱識別碼。您取得權杖簽署憑證的方式就和在 SharePoint 2010 的做法一樣 – 前往伺服器陣列中的伺服器、執行 MMC、為本機電腦新增 [憑證] 嵌入式單元、查看 SharePoint… [憑證] 節點,清單中的第一個憑證就是您要的 – 將它以 .cer 檔案格式存在本機硬碟中,不要儲存私密金鑰。您需要我之前說過的 STS 的憑證和 NameIdentifier 屬性,才能建立信任。如此一來,Cmdlet 會像這樣 (它假定您將 STS 憑證複製到 FARM_B 伺服器中名為 C:\sts.cer 的檔案):
$i = New-SPTrustedSecurityTokenIssuer -name FARM_A -Certificate "C:\sts.cer" -RegisteredIssuerName "00000003-0000-0ff1-ce00-000000000000@72da1552-085a-49de-9ecb-73ba7eca8fef " -Description "FARM_A description" -IsTrustBroker:$false
就和 SPTrustedIdentityTokenIssuer 的執行方式一樣,您要將簽署 oAuth 權杖的信任加入 SharePoint 中信任的根授權單位清單中。同樣地,您有兩個選擇:如果您透過中繼資料端點建立信任,您可以如下方式建立信任:
New-SPTrustedRootAuthority -Name FARM_A -MetadataEndPoint https://FARM_A/_layouts/15/metadata/json/1/rootcertificate
不然,您可以將它加入受信任的根授權單位清單中,就和在 SharePoint 2010 的做法一樣:
$root = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\sts.cer")
New-SPTrustedRootAuthority -Name "Token Signing Root CA Certificate" -Certificate $root
以信任的角度來看,您做到這一步已經完成了 – 您的信任已經建立,現在您可以根據它建立新的應用程式主體。您要如何使用信任視應用程式本身而定;在遠端 SharePoint 索引這個例子中,為了完整,我現在要繼續把這個案例說完。
在這個程序有兩個步驟 – 取得應用程式主體並授予權限。還記得在我們的例子中,FARM_B 需要來自 FARM_A 的信任呼叫,因為它要取得遠端 SharePoint 索引的查詢。所以,我需要為我的應用程式主體取得 FARM_B 的 Web 應用程式參照,讓 FARM_A 使用。我一取得參照,就可以授權讓 FARM_A 使用。
要取得應用程式主體的參照,您要使用這樣的 Cmdlet:
$p = Get-SPAppPrincipal -Site https://FARM_B -NameIdentifier $i.NameId
重要: 這裡有一件重要的事情要注意,我覺得尤其在 SharePoint 2013 Beta 會特別常見。在您嘗試取得 SPAppPrincipal 時,您可能會在 PowerShell 遇到奇怪的錯誤。我發現,當您伺服器的可用記憶體空間少於 5%,所有的 WCF 呼叫都會失敗。因為這個 PowerShell Cmdlet 呼叫至服務應用程式端點,而該端點以 WCF 託管,因此當您的記憶體空間太少,Get-SPAppPrincipal Cmdlet 就會失敗。您可以查看 [應用程式記錄檔] 中的 [Windows 事件檢視器],看看這是不是造成您問題的原因。這個問題我目前已經碰到過很多次,所以其他人也很可能會遇到。
請注意,我在這篇文章的前面有提過,我最後可以用 $i 變數來取得在 FARM_A 的 STS 的 NameIdentifier。既然我現在已經有了 FARM_B Web 應用程式的應用程式主體參照,我可以像這樣予與授權:
Set-SPAppPrincipalPermission -Site https://FARM_B -AppPrincipal $p -Scope SiteSubscription -Right FullControl
就這麼簡單 – 以上就是在兩個 SharePoint 伺服器陣列間建立 oAuth 信任的選項和方法。日後我會繼續在這個部落格討論 oAuth 和各種該知道的用途和問題。
這是翻譯後的部落格文章。英文原文請參閱 Setting Up an oAuth Trust Between Farms in SharePoint 2013