如何在Java中使用LDAP认证Exchange Web Services连接?

5

我想写一个Java应用程序以访问Exchange Web Services来读取电子邮件。因此,我使用由Microsoft提供的Exchange Web Services (EWS) Java API。

我已经遇到了一些问题,最终发现身份验证应该使用LDAP进行。不幸的是,我不知道如何做这样的事情。EWS API是否允许配置连接到Exchange服务器时要使用的认证方案?如果可以,如何配置?

这是我用于连接的代码,但它使用默认的认证方案,即NTLM

String url = "https//my-server/EWS/exchange.asmx";
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.setTraceEnabled(true);
service.setCredentials(new WebCredentials("user", "password"));
service.setUrl(url.toURI());

Mailbox mailbox = new Mailbox("foo@bar.com");
FolderId folder = new FolderId(WellKnownFolderName.Inbox, mailbox);
ItemView view = new ItemView(10);
view.getOrderBy().add(ItemSchema.DateTimeReceived, SortDirection.Descending);
FindItemsResults<Item> items = service.findItems(folder, view);
2个回答

3
我们解决了这个问题。实际上,我们有两个解决方案:
在Microsoft EWS API中,类NTLM是错误的。因此,我们使用以下代码重新构建了该类的JAR文件:
private class NTLM {
    /** Character encoding */
    public static final String DEFAULT_CHARSET = "ASCII";

    /**
    * The character was used by 3.x's NTLM to encode the username and
    * password. Apparently, this is not needed in when passing username,
    * password from NTCredentials to the JCIFS library
    */
    private String credentialCharset = DEFAULT_CHARSET;

    void setCredentialCharset(String credentialCharset) {
           this.credentialCharset = credentialCharset;
    }

    private static final int TYPE_1_FLAGS = NtlmFlags.NTLMSSP_NEGOTIATE_NTLM
                 | NtlmFlags.NTLMSSP_NEGOTIATE_UNICODE
                 | NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2;

    private String generateType1Msg(String host, String domain) {
           jcifs.ntlmssp.Type1Message t1m = new jcifs.ntlmssp.Type1Message(
                        TYPE_1_FLAGS, domain, host);
           return jcifs.util.Base64.encode(t1m.toByteArray());
    }

    private String generateType3Msg(String username, String password,
                 String host, String domain, String challenge) {
           jcifs.ntlmssp.Type2Message t2m;
           try {
                 t2m = new jcifs.ntlmssp.Type2Message(
                               jcifs.util.Base64.decode(challenge));
           } catch (IOException e) {
                 throw new RuntimeException("Invalid Type2 message", e);
           }

           final int type2Flags = t2m.getFlags();
           final int type3Flags = type2Flags
                        & (0xffffffff ^ (NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER));

           jcifs.ntlmssp.Type3Message t3m = new jcifs.ntlmssp.Type3Message(
                        t2m, password, domain, username, host, type3Flags);
           return jcifs.util.Base64.encode(t3m.toByteArray());
    }
}

另一种解决方案是使用JWebServices库(商业)。

我按照这些说明进行了操作,修改了NTLM并且完全按照此处描述的编译源代码,但仍然收到相同的错误消息。我们最终决定在此处使用javamail实现,它可以正常工作:https://dev59.com/nW855IYBdhLWcg3wcz5h#18043717 - Eric Leschinski
这个类是EwsJCIFSNTLMScheme(api 1.2)中的内部类。 - oers

0

我们曾经遇到过同样的问题,虽然更改NTLM类(如romaintaz所建议的)可以解决问题,但在其他地方会出现错误。

然而,有一个更新版本的EWS Java库,托管在github上: https://github.com/OfficeDev/ews-java-api

它现在使用apache httpclient 4.4.1,具有良好的NTLM实现。

使用这个库,我们目前没有关于NTLM身份验证的任何问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接