2017-03-07 30 views
3

我有一個守護進程訪問某些用戶的電子郵件以便自動轉發它們。我在Azure中註冊了守護進程並請求了許多由管理員授予的應用程序權限。 然後,我可以獲得oAuth2令牌,並且應用程序按照預期運行。使用來自使用Microsoft Graph的守護進程的委託權限

現在我的IT部門問我,如果不是每個郵箱都擁有完整的權限,應用程序可以模擬一個用戶,以便只有該用戶的電子郵件可以被守護程序讀取和轉發。

因此,我在Azure上註冊了另一個應用程序,只請求委託權限(我選擇了不需要管理員批准的所有委託權限,共44項)。 然後,我構建了我的授權URL並將其發送給相關用戶。用戶點擊鏈接,獲得了應用程序請求的所有權限列表,並同意將這些權限授予應用程序。

我的應用程序隨後收到授權碼,如預期的那樣。然後MS documentation聲明我可以使用該代碼獲取用於訪問用戶郵箱的令牌。所以,我建立了利用微軟提供的其他說明參數:

"grant_type=authorization_code" + 
"&client_id={appID}+ 
"&client_secret={appSecret} + 
"&code={auth_code}+ 
"&redirect_uri={Same_Redirect_URI_used_when_obtaining_Authorization_Code} + 
"&resource=https://graph.microsoft.com"  

而且我發出了與此內容的授權URL POST請求,如文檔中規定:

https://login.microsoftonline.com/{myTenantID}/oauth2/token 

現在的怪關於這一點的是,只要我的腳本運行xhr.send(tmpSnd);方法(其中tmpSnd包含上述REST參數),我立即得到msxml3.dll: Access is denied error。至少,我希望這個錯誤能夠作爲POST反應的一部分回來,但我甚至從來沒有通過send()方法。

這裏的JS代碼,我使用它來獲取令牌:

this.getDelegatedToken = function(appEndPoint, appID, appSecret,auth_Code,appURI){ 
    var result=null; 
    var GRAPH_URL_TOKEN = "https://login.microsoftonline.com/" + appEndPoint + "/oauth2/token"; 
    xhr.open("POST", GRAPH_URL_TOKEN, false); 
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 

    var params ="grant_type=authorization_code" + 
     "&client_id="  + appID + 
     "&client_secret=" + appSecret + 
     "&code="   + auth_Code+ 
     "&redirect_uri=" +appURI + 
     "&resource=https://graph.microsoft.com"; 

    xhr.send(params); 
    if(xhr.status==200) { 
     result = JSON.parse(xhr.responseText); 
    } 
    return result; 
    }; 

我覺得我讀的地方,只使用委託權限可能會導致守護進程的問題,但對我的生活我不記得我讀它的地方(使用Graph需要大量閱讀!)。

EDIT

如果我設置&代碼參數爲無效值,我收到預期的錯誤消息(「代碼格式不正確或無效」)。如果我將它設置爲之前的授權碼,並且過期,我也會收到預期的錯誤消息(「提供的授權碼或刷新碼已過期」)。所以看起來我所有的POST參數都是有效的,因爲當我故意傳遞一個無效的錯誤消息時,我會收到正確的錯誤消息。我只是不明白爲什麼,當我通過所有正確的參數時,我甚至不會收到錯誤響應,我只能從XHR對象獲取訪問被拒絕的消息。

任何人都可以在代碼或過程中發現任何明顯的錯誤嗎?

+0

您是否正在從前端JavaScript運行該應用程序? – juunas

+0

我正在從Windows腳本宿主的應用內實例運行此操作。沒有涉及網絡瀏覽器。應用程序本身作爲Windows服務運行,這意味着不涉及GUI。在某種程度上,它與NodeJS的功能相似。除了NodeJS之外,它是一個Windows可執行文件(用Delphi編寫)實現了WSH。 希望能回答你的問題。 – Filipus

+0

只是想確認您的tenantID(名爲appEndPoint的變量)看起來像「contoso.com」(當然,對於您的組織)。 – piisexactly3

回答

0

一旦您擁有授權碼,您需要對令牌端點進行POST。見here

現在你已經獲得的授權碼和用戶已被授予 許可,您可以兌換一個訪問令牌代碼 所需的資源,通過發送POST請求/token 端點:

//換行符的可讀性只

POST /{tenant}/oauth2/token HTTP/1.1 
Host: https://login.microsoftonline.com 
Content-Type: application/x-www-form-urlencoded 
grant_type=authorization_code 
&client_id=2d4d11a2-f814-46a7-890a-274a72a7309e 
&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrqqf_ZT_p5uEAEJJ_nZ3UmphWygRNy2C3jJ239gV_DBnZ2syeg95Ki-374WHUP-i3yIhv5i-7KU2CEoPXwURQp6IVYMw-DjAOzn7C3JCu5wpngXmbZKtJdWmiBzHpcO2aICJPu1KvJrDLDP20chJBXzVYJtkfjviLNNW7l7Y3ydcHDsBRKZc3GuMQanmcghXPyoDg41g8XbwPudVh7uCmUponBQpIhbuffFP_tbV8SNzsPoFz9CLpBCZagJVXeqWoYMPe2dSsPiLO9Alf_YIe5zpi-zY4C3aLw5g9at35eZTfNd0gBRpR5ojkMIcZZ6IgAA 
&redirect_uri=https%3A%2F%2Flocalhost%2Fmyapp%2F 
&resource=https%3A%2F%2Fservice.contoso.com%2F 
&[email protected] 

//NOTE: client_secret only required for web apps 

它似乎並不像你在你的代碼中正確地做到了這一點。讓我知道如果這有幫助!

+0

對不起,我在複製/粘貼代碼時犯了錯誤...我現在已在原始帖子中更正了它們。正如你所看到的,我使用的是與MS文檔中指定的完全相同的值,但在調用xhr.send()方法時,我仍然會得到相同的「訪問被拒絕」錯誤(順便說一句,xhr是一個實例\t Microsoft.XMLHTTP) – Filipus

0

我假設,當你使用客戶端的祕密,你得到應用程序唯一的token.This令牌沒有資源的訪問。要使用App Only令牌訪問資源,您需要在Azure門戶上獲得應用程序權限(而不是委派)。添加應用程序權限檢查並查看您是否仍然獲得訪問被拒絕錯誤

+0

正如我在我的初始文章中解釋的,我知道使用應用程序權限的原理,但我的IT部門希望我使用委託權限,這就是我遇到麻煩的地方。 – Filipus

+0

您需要守護進程在用戶帳戶(委託)上運行。不是每個用戶帳戶都運行的服務。即使您使用任何Web鉤子(可以使用委託)並從守護進程調用,我無法想象一種在不涉及用戶的情況下獲取用戶上下文的方式。 –

+0

守護程序必須能夠訪問_only_用戶已授予其權限的帳戶。如果守護程序使用應用程序權限,則它可以訪問所有帳戶,這是我的IT部門不喜歡的。守護程序具有要監視的帳戶列表,並且對於這些帳戶中的每個帳戶,它必須能夠檢索並轉發消息。 – Filipus