我关注此帖:Outlook RestGettingStarted。从我的Java应用程序,我试图获得AccessToken和RefreshToken。当我发出授权代码请求时,它结束为以下错误:
很抱歉,但我们在登录时遇到了麻烦。我们收到了不好的消息 请求。
其他技术信息:相关ID: ed838d66-5f2e-4cfb-9223-a29082ecb26f时间戳:2015-08-20 10:20:09Z AADSTS90011:'资源'请求参数不受支持。
注意:根据文档说明网址格式正确。
所以,我删除了#34;资源"从我的代码查询参数。并重定向在浏览器中授权URL。在用户同意后,我获得了授权码。使用此代码我获得了AccessToken。但是,当我尝试连接Outlook IMAP服务器时,它失败了。 Java参考链接了解详细信息:Java OAuth2 但它给了我错误:
[AUTHENTICATIONFAILED] OAuth身份验证失败。
注意:我添加了正确的范围和用户电子邮件。
然后使用获得的访问令牌我进行了Mail Rest API调用以从用户收件箱中获取邮件。它结束了以下错误:
HTTP响应: {"错误":{"代码":" MailboxNotEnabledForRESTAPI","消息":" REST API是 此邮箱尚不支持。"}}
任何人都可以帮助我关注:
确切原因是什么:" AADSTS90011:'资源'请求参数不受支持"在遵循Outlook开发文档之后。
如何解决" MailboxNotEnabledForRESTAPI"错误。
是否可以使用正确的AccessToken使用java邮件API连接到Outlook IMAP服务器?
答案 0 :(得分:0)
我最近碰到了这个,但不记得哪个解决了它。一个主要问题是在文档中它是变化的。它会告诉你附加" resource",但那是像Azure这样的东西。
以下是我使用的代码:
首先发送请求:
private static final String USER_OAUTH2_AUTHORIZE_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";
public String getOAuthDialog(Http.Request request) {
return USER_OAUTH2_AUTHORIZE_URL
+ "?client_id=" + config.getClientId()
+ "&redirect_uri=" + getOutlookLoginRedirect(request)
+ "&response_type=code"
+ "&scope=https%3A%2F%2Foutlook.office.com%2Fmail.send%20" +
"https%3A%2F%2Foutlook.office.com%2Fmail.readwrite%20" +
"offline_access%20openid%20email%20profile"
+ "&state=" + crypto.generateSignedToken();
}
范围是最困难的事情。我找到了许多不起作用的。并且我不清楚我需要用空格分隔它们。
然后他们会向您发送一个请求到您提供的重定向网址。它将包含您需要交换的范围内所请求数据的代码。提供的重定向网址必须完全相同。您还需要在平台 - >添加平台 - >重定向URI->添加网址
下的应用程序门户上注册重定向网址 private static final String USER_ACCESS_TOKEN_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
private Map<String, String> sendOutlookUserOAuthRequest(Http.Request request, String code) {
WSClient ws = WS.client();
HttpParameters params = new HttpParameters();
params.put("client_id", config.getClientId(), true);
params.put("client_secret", config.getClientSecret(), true);
params.put("code", code, true);
params.put("redirect_uri", getOutlookLoginRedirect(request), true);
params.put("grant_type", "authorization_code");
String postParams = OAuthUtil.parametersToString(params);
WSRequest wsRequest = ws.url(USER_ACCESS_TOKEN_URL)
.setMethod("POST")
.setContentType("application/x-www-form-urlencoded")
.setBody(postParams);
WSResponse wsResponse = wsRequest.execute().get(10, TimeUnit.SECONDS);
Map<String, String> result = new HashMap<>();
if (wsResponse.getStatus() != HttpStatus.SC_OK) {
return result;
}
JsonNode node = wsResponse.asJson();
if (node.hasNonNull("access_token")) {
result.put("access_token", node.get("access_token").asText());
}
if (node.hasNonNull("refresh_token")) {
result.put("refresh_token", node.get("refresh_token").asText());
}
if (node.hasNonNull("id_token")) {
String[] tokenSplit = node.get("id_token").asText().split("\\.");
if (tokenSplit.length >= 2) {
try {
JSONObject jsonObject = new JSONObject(new String(Base64.getDecoder().decode(tokenSplit[1])));
if (jsonObject.has("name")) {
result.put("name", jsonObject.get("name").toString());
}
if (jsonObject.has("email")) {
result.put("outlookUid", jsonObject.get("email").toString());
} else if (jsonObject.has("preferred_username")) {
result.put("outlookUid", jsonObject.get("preferred_username").toString());
}
} catch (JSONException e) {
log.error("Error extracting outlookUid from id_token: ", e);
}
}
}
return result;
}
您可能需要的另一个请求是更新刷新令牌:
private String getAccessTokenFromRefreshToken(User user) {
WSClient ws = WS.client();
HttpParameters params = new HttpParameters();
params.put("client_id", config.getClientId(), true);
params.put("client_secret", config.getClientSecret(), true);
params.put("grant_type", "refresh_token");
params.put("refresh_token", user.getOutlookRefreshToken());
String postParams = OAuthUtil.parametersToString(params);
WSRequest wsRequest = ws.url(USER_ACCESS_TOKEN_URL)
.setMethod("POST")
.setContentType("application/x-www-form-urlencoded")
.setBody(postParams);
WSResponse wsResponse = wsRequest.execute().get(10, TimeUnit.SECONDS);
if (wsResponse.getStatus() != HttpStatus.SC_OK) {
log.error("Failure to refresh outlook access token for user: " + user +
". Received status: " + wsResponse.getStatus() + " : " + wsResponse.getStatusText());
return null;
}
JsonNode node = wsResponse.asJson();
if (node.hasNonNull("access_token")) {
String accessToken = node.get("access_token").asText();
return accessToken;
} else {
log.error("Outlook refresh token failure, 'access_token' not present in response body: " + wsResponse.getBody());
return null;
}
}
我遇到的一个问题花了比我希望的更长的时间来获取clientId和clientSecret。这是因为微软使用的语言并不是最明确的。客户端ID和应用程序ID可互换使用。客户端密钥也是您在Application Portal上创建的密码,不要与您可以生成的私钥混淆。
所以你实际上想要application_id和密码,尽管他们将它们称为client_id和client_secret,并没有直接指示绘制的线条。
这是假设您已在Outlook Application Portal上设置应用程序。 https://apps.dev.microsoft.com/
我希望这会有所帮助,虽然我认为你可能已经解决了这个问题。