簡體   English   中英

使用 oAuth2 訪問 Office365 的 EWS API

[英]EWS API to access Office365 with oAuth2

我們有一個守護程序應用程序,它使用 EWS API 通過基本身份驗證訪問 office365/Exchange 服務器。 我正在嘗試實施 Oauth2。 有很多文件。 但是,它們通常已經過時並引起了更多的混亂。 我遵循了這個文檔https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-daemon-overview ,它似乎是最新的。 我做了以下步驟:

注冊應用

文檔: https : //docs.microsoft.com/en-us/azure/active-directory/develop/scenario-daemon-app-registration - 在 Azure AD 中使用應用程序密碼注冊一個機密,即使用證書。 生成的秘密被記錄下來。 - 選擇“僅限此組織目錄中的帳戶”。
- 請求對 Exchange full_access_as_app 和 Mail.Read 的應用程序權限的 API 權限。 授予管理員同意。

獲取令牌

文檔: https : //docs.microsoft.com/en-us/azure/active-directory/develop/scenario-daemon-acquire-token?tabs=java我原型使用協議來獲取令牌

 POST /{tenant}/oauth2/v2.0/token HTTP/1.1           
 Host: login.microsoftonline.com
 Content-Type: application/x-www-form-urlencoded

 client_id={myAppClientId}
 &scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
 &client_secret={myAppSecret}
 &grant_type=client_credentials

我得到了令牌

{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 3599,
"access_token": "……thetoken…"

}

在我的應用程序中調用 EWS API

我的應用程序使用基本身份驗證。 我通過添加 Authorization 標頭(“Authorization”、“Bearer”+ accessToken)對其進行了修改; 基本上,prepareWebRequest() 函數是通過添加 Authorization 標頭來覆蓋的。 與基本身份驗證情況相比,請求具有額外的授權標頭和承載令牌。

對於基本授權已起作用的同一個 EWS API 調用,響應為 401,x-ms-diagnostics 2000003;reason="受眾聲明值對當前資源無效。受眾聲明是“ https://graph.microsoft。 com ',請求 url 是 ' https://outlook.office365.com/EWS/Exchange.asmx ',資源類型是 'Exchange'。";error_category="invalid_resource"

在 stackoverflow 中研究,人們建議使用以下作為范圍值來獲取第 2 步中的令牌: https://outlook.office365.com/full_access_as_app https://outlook.office.com/Mail.Read我試過,都返回了“ invalid_scope”錯誤。 似乎兩者以前都有效,但不再有效。 按照工作范圍值格式,我嘗試使用https://outlook.office.com/.default作為范圍值。 我能夠得到一個令牌! 但是,當我在 EWS API 中使用此令牌訪問郵箱時,我收到了 500 錯誤而不是 401。
應該怎樣做才能讓它發揮作用? 訪問 office365 郵箱的正確范圍是什么?

更多代碼片段

這是為 oauth2 添加的新類

package microsoft.exchange.webservices.data;
import java.util.Map;
public final class BearerTokenCredentials extends ExchangeCredentials {

private static final String BEARER_TOKEN_FORMAT_REGEX = "^[-._~+/A-Za-z0-9]+=*$";
private static final String AUTHORIZATION = "Authorization";
private static final String BEARER_AUTH_PREAMBLE = "Bearer ";
private String token;
public String getToken() {
    return token;
}
public BearerTokenCredentials(String bearerToken) {
    if (bearerToken == null) {
        throw new IllegalArgumentException("Bearer token can not be null");
    }
    this.validateToken(bearerToken);
    this.token = bearerToken;
}
protected void validateToken(String bearerToken) throws IllegalArgumentException {
    if (!bearerToken.matches(BEARER_TOKEN_FORMAT_REGEX)) {
        throw new IllegalArgumentException("Bearer token format is invalid.");
    }
}
@Override
public void prepareWebRequest(HttpWebRequest request) {
    Map<String, String> headersMap = request.getHeaders();
    String bearerValue = BEARER_AUTH_PREAMBLE + token;
    headersMap.put(AUTHORIZATION, bearerValue);
    //headersMap.put("X-AnchorMailbox","esj_office365_imap@genesyslab.onmicrosoft.com");
    request.setHeaders(headersMap);
}

}

使用令牌訪問 EWS/Exchange ews-java-api 2.0-patched

ExchangeService service  = new 
ExchangeService(ExchangeVersion.Exchange2010_SP2); //version is 
Exchange2010_SP2
service.setTraceEnabled(true);
BearerTokenCredentials credentials = new BearerTokenCredentials("thetoken");
service.setCredentials(credentials);
service.setUrl(new 
URI(host));//https://outloook.office365.com/EWS/Exchange.asmx
try{
Folder.bind(service, WellKnownFolderName.Inbox); 
}catch(Exception e)
{
//The remote server returned an error: (500)Internal Server Error
}

您用於連接到 Office365 郵箱的代碼仍然需要使用 EWS Impersonation eg

service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailboxName);

其中 MailboxName 是您要連接的郵箱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM