我想補充細節,以解決上面我的評論簡要提及 - 這將是任何人在Office 365開發多租戶應用程序很重要,尤其是如果應用程序將永遠訪問SharePoint網站,包括OneDrive。
從OAuth 2.0的角度來看,這裏的程序有點不標準,但在多租戶領域有一定意義。關鍵是重新使用從Azure返回的第一個CODE。在這裏跟我來:
首先,我們按照標準的OAuth認證步驟:
GET /common/oauth2/authorize?client_id=5cb5e93b-57f5-4e09-97c5-e0d20661c59a
&redirect_uri=https://myappdomain.com/v1/oauth2_redirect/
&response_type=code&prompt=login&state=D79E5777 HTTP/1.1
Host: login.windows.net
Cache-Control: no-cache
這重定向到Azure的登錄頁面,在用戶登錄如果成功,天青然後調用回你的端點代碼。 :
https://myappdomain.com/v1/oauth2_redirect/?code=AAABAAAA...{ONE-CODE-To-RULE-THEM-ALL}xyz
現在我們回發到/token
終端獲取的實際承載令牌在後續REST調用中使用。再次,這只是傳統的OAuth2 ...但請注意我們如何將/Discovery
端點用作資源 - 而不是我們實際用於收集數據的任何端點。另外,我們要求UserProfile.Read
範圍。
POST /common/oauth2/token HTTP/1.1
Host: login.windows.net
Accept: text/json
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="grant_type"
authorization_code
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="code"
AAABAAAA...{ONE-CODE-To-RULE-THEM-ALL}xyz
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="client_id"
5cb5e93b-57f5-4e09-97c5-e0d20661c59a
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="client_secret"
02{my little secret}I=
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="redirect_uri"
https://myappdomain.com/v1/oauth2_redirect/
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="scope"
UserProfile.Read
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="resource"
https://api.office.com/discovery/
----WebKitFormBoundaryE19zNvXGzXaLvS5C
這個主題的響應將包含可用於製造REST調用的/discovery
端點的access-token
。現在
{
"refresh-token": "AAABsvRw-mAAWHr8XOY2lVOKZNLJ{BAR}xkSAA",
"resource": "https://api.office.com/discovery/",
"pwd_exp": "3062796",
"pwd_url": "https://portal.microsoftonline.com/ChangePassword.aspx",
"expires_in": "3599",
"access-token": "ey_0_J0eXAiOiJjsp6PpUhSjpXlm0{F00}-j0aLiFg",
"scope": "Contacts.Read",
"token-type": "Bearer",
"not_before": "1422385173",
"expires_on": "1422389073"
}
,使用這種access-token
,查詢/Services
端點找出是Office 365的該用戶提供什麼。
GET /discovery/v1.0/me/services HTTP/1.1
Host: api.office.com
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5D
Content-Disposition: form-data; name="Authorization"
Bearer ey_0_J0eXAiOiJjsp6PpUhSjpXlm0{F00}-j0aLiFg
----WebKitFormBoundaryE19zNvXGzXaLvS5D
結果將包括一個服務結構數組,描述每個端點的各種端點和功能。
{
"@odata.context": "https://api.office.com/discovery/v1.0/me/$metadata#allServices",
"value": [
{
"capability": "MyFiles",
"entityKey": "[email protected]_SHAREPOINT",
"providerId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
"serviceEndpointUri": "https://contoso-my.sharepoint.com/_api/v1.0/me",
"serviceId": "O365_SHAREPOINT",
"serviceName": "Office 365 SharePoint",
"serviceResourceId": "https://contoso-my.sharepoint.com/"
},
{
"capability": "RootSite",
"entityKey": "[email protected]_SHAREPOINT",
"providerId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
"serviceEndpointUri": "https://contoso.sharepoint.com/_api",
"serviceId": "O365_SHAREPOINT",
"serviceName": "Office 365 SharePoint",
"serviceResourceId": "https://contoso.sharepoint.com/"
},
{
"capability": "Contacts",
"entityKey": "[email protected]_EXCHANGE",
"providerId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
"serviceEndpointUri": "https://outlook.office365.com/api/v1.0",
"serviceId": "O365_EXCHANGE",
"serviceName": "Office 365 Exchange",
"serviceResourceId": "https://outlook.office365.com/"
}
]
}
現在到了棘手的部分...在這一點上,我們知道,我們真的要驗證端點 - 其中一些是租戶特定的。通常情況下,你會認爲我們需要重新演奏這些終結點的OAuth2舞蹈。但是在這種情況下,我們可以使用上面相同的HTTP請求,只是簡單地發佈與我們最初從Azure收到的代碼相同的代碼 - 僅使用上述Service結構中的serviceResourceId
和capability
來更改resource
和scope
字段。就像這樣:
POST /common/oauth2/token HTTP/1.1
Host: login.windows.net
Accept: text/json
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="grant_type"
authorization_code
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="code"
AAABAAAA...{ONE-CODE-To-RULE-THEM-ALL}xyz
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="client_id"
5cb5e93b-57f5-4e09-97c5-e0d20661c59a
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="client_secret"
02{my little secret}I=
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="redirect_uri"
https://myappdomain.com/v1/oauth2_redirect/
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="scope"
MyFiles.Read
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="resource"
https://contoso-my.sharepoint.com/
----WebKitFormBoundaryE19zNvXGzXaLvS5C
然後做同樣的其他兩個:
...
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="scope"
RootSite.Read
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="resource"
https://contoso.sharepoint.com/
----WebKitFormBoundaryE19zNvXGzXaLvS5C
和
...
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="scope"
Contacts.Read
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="resource"
https://outlook.office365.com/
----WebKitFormBoundaryE19zNvXGzXaLvS5C
所有這三個調用將導致像第一篇文章的響應上面的,爲您提供每個相應端點的刷新令牌和訪問令牌。所有這些僅以單一用戶身份驗證的價格提供。 :)
中提琴!神祕解決了 - 您可以爲O365編寫多租戶應用程序。 :)
啊,最後。經過數小時的研究,實驗和開發 - 我偶然發現了一個解決方案!這是Azure/O365 API的一個未記錄的「特性」,所以我想確保每個對此主題感興趣的人都能發現關鍵:顯然通過資源「https://api.office」向Azure端點進行身份驗證。com/discovery /「會生成一個可以在POST to/token步驟中多次使用的CODE - 允許您對」discovery/v1.0/me/services「進行REST調用並遍歷結果,獲取令牌每個人都有相同的代碼值。不客氣:) – 2015-01-26 20:13:45
回顧:[http://yazezo.com/2013/10/how-to-setup-saas-cloud-multi-tenant.html](How設置一個SaaS雲?多租戶,CRM 2011,Outlook2010) – 2015-09-25 16:02:46