EWS API使用oAuth2访问Office365

问题描述 投票:0回答:1

我们有一个Daemon应用程序,该应用程序使用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)修改了它;很容易通过添加Authorization标头覆盖prepareWebRequest()函数。与基本身份验证案例相比,该请求具有带有承载令牌的附加授权标头。

对于基本授权已使用的同一EWS API调用,响应为401,其中X-MS诊断2000003; reason =“受众声明值对于当前资源无效。受众声明为'https://graph.microsoft.com',请求网址为'https://outlook.office365.com/EWS/Exchange.asmx',资源类型为'Exchange'。”; error_category =“ invalid_resource”

在stackoverflow中进行了研究,人们建议在步骤2中使用以下内容作为范围值来获取令牌:https://outlook.office365.com/full_access_as_apphttps://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","[email protected]");
    request.setHeaders(headersMap);
}

}

使用令牌访问EWS / Exchange ews-java-api 2.0已修补的补丁

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
}
java azure oauth-2.0 exchangewebservices
1个回答
0
投票

您用于连接到Office365邮箱的代码仍然需要使用EWS模拟,例如

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

其中MailboxName是您要连接的邮箱。

© www.soinside.com 2019 - 2024. All rights reserved.