首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用OAUTH2访问outlook.office 365.com IMAP表单Java?

如何使用OAUTH2访问outlook.office 365.com IMAP表单Java?
EN

Stack Overflow用户
提问于 2022-10-21 18:38:56
回答 1查看 1.4K关注 0票数 2

由于微软已经宣布不久将不可能访问具有基本身份验证的Outlook邮箱,因此我正在设法找出如何使用OAUTH2在Java中正确地打开IMAP邮箱。但是我总是得到错误代码"A1 NO身份验证失败“。

我要做的是:

我有一个生成OAUTH2访问令牌的方法:

代码语言:javascript
运行
复制
public String getAuthToken(String tanantId,String clientId,String client_secret) throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost loginPost = new HttpPost("https://login.microsoftonline.com/" + tanantId + "/oauth2/v2.0/token");
    String scopes = "https://outlook.office365.com/.default";
    String encodedBody = "client_id=" + clientId + "&scope=" + scopes + "&client_secret=" + client_secret
            + "&grant_type=client_credentials";
    loginPost.setEntity(new StringEntity(encodedBody, ContentType.APPLICATION_FORM_URLENCODED));
    loginPost.addHeader(new BasicHeader("cache-control", "no-cache"));
    CloseableHttpResponse loginResponse = client.execute(loginPost);
    InputStream inputStream = loginResponse.getEntity().getContent();
    byte[] response = readAllBytes(inputStream);
    ObjectMapper objectMapper = new ObjectMapper();
    JavaType type = objectMapper.constructType(
            objectMapper.getTypeFactory().constructParametricType(Map.class, String.class, String.class));
    Map<String, String> parsed = new ObjectMapper().readValue(response, type);
    return parsed.get("access_token");
}

生成的令牌似乎是有效的,因为jwt.ms允许我解码令牌。

我尝试使用访问令牌通过XOAUTH2访问邮箱,如下所示:

代码语言:javascript
运行
复制
        Properties props = new Properties();

        props.put("mail.store.protocol", "imap");
        props.put("mail.imap.host", "outlook.office365.com");
        props.put("mail.imap.port", "993");
        props.put("mail.imap.ssl.enable", "true");
        props.put("mail.imap.starttls.enable", "true");
        props.put("mail.imap.auth", "true");
        props.put("mail.imap.auth.mechanisms", "XOAUTH2");
        props.put("mail.imap.user", mailAddress);
        props.put("mail.debug", "true");
        props.put("mail.debug.auth", "true");
    
        // open mailbox....
        String token = getAuthToken(tanantId,clientId,client_secret);
        Session session = Session.getInstance(props);
        session.setDebug(true);
        Store store = session.getStore("imap");
        store.connect("outlook.office365.com", mailAddress, token);

但是结果总是一个AuthenticationFailedException

代码语言:javascript
运行
复制
* OK The Microsoft Exchange IMAP4 service is ready. [...............AA==]
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG IMAP: AUTH: PLAIN
DEBUG IMAP: AUTH: XOAUTH2
DEBUG IMAP: protocolConnect login, host=outlook.office365.com, user=xxx@yyy.com, password=<non-null>
A1 AUTHENTICATE XOAUTH2 ....E=
A1 NO AUTHENTICATE failed.
javax.mail.AuthenticationFailedException: AUTHENTICATE failed.

这个类似的问题,我现在怀疑我的访问令牌实际上拥有的访问邮箱的权限太少。

我如何澄清这一点?例如,当我解码令牌时,我可以看到它没有包含scproles属性。这是否表明令牌错误?

EN

回答 1

Stack Overflow用户

发布于 2022-10-24 15:08:39

代码示例是正确的。问题在于所提供的servicePrincipal上缺少的权限。要在servicePrincipal中创建office365,需要使用objectId。这些任务只能由管理员使用PowerShell脚本执行。这些都与Java无关。Java是直接的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74157939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档