在Java中验证NTLMv2身份验证

时间:2012-06-22 19:38:47

标签: java authentication netbeans ntlm ntlmv2

所以我试图用NTLMv2和Java来追踪一个奇怪的错误。似乎NTLM忽略了我在基于Java的身份验证期间传递的任何信息,并在其他地方查找信息。因此,NTLM将在我的机器上进行身份验证,即使我提供的信息不正确,即使提供了正确的信息,NTLM也无法在任何其他计算机上运行。如果相关,则端点是MOSS 2007 Web服务API。

以下是我用于验证的过程:

1)传入目标站点并登录信息。

try {
    JLists list = new JLists(siteUrl, DEFAULT_SP_USERNAME,
        DEFAULT_SP_PASSWORD);
    list.addList(name, description, 101);

} catch (Exception e) {
     e.printStackTrace();
}


2)将默认验证器设置为我自己的NTLMAuthenticator, 创建服务存根并传入登录信息。

public JLists(String siteURI, String username, String password)
        throws Exception {

    String endpointURI = siteURI + "/_vti_bin/Lists.asmx";

    Authenticator.setDefault(new NtlmAuthenticator(username, password));

    port = sharePointListsAuth(username, password);
    BindingProvider bp = (BindingProvider) port;
    bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
            endpointURI);
}

private ListsSoap sharePointListsAuth(String userName, String password) throws Exception {
    ListsSoap port = null;
    if (userName != null && password != null) {
        try {
            service = new Lists();
            port = service.getListsSoap();
            ((BindingProvider) port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName);
            ((BindingProvider) port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
        } catch (Exception e) {
            throw new Exception("Error: " + e.toString());
        }
    } else {
        throw new Exception("Couldn't authenticate: Invalid connection details given.");
    }
    return port;
}


这里是NTLMAuthenticator类的副本:

import java.net.Authenticator;
import java.net.PasswordAuthentication;

class NtlmAuthenticator extends Authenticator {

  private final String username;
  private final char[] password;

  public NtlmAuthenticator(final String username, final String password) {
    super();
    this.username = username;
    this.password = password.toCharArray(); 
  }

  public PasswordAuthentication getPasswordAuthentication() {
    return (new PasswordAuthentication (username, password));
  }
}

3)拨打我的服务电话。我在这方面没有遇到任何问题,但如果有人需要代码,我也会发布。

我觉得Java在某种程度上引用了我的Active Directory信息,并使用它来代替提供的信息,但我不知道会发生什么情况。

2 个答案:

答案 0 :(得分:1)

似乎问题是基于Java" Single Sign-On"功能。因为我在Windows机器上尝试NTLM身份验证,所以Java有一个硬编码值,默认为当前帐户的登录信息,然后仅在失败时才使用Java身份验证器。

似乎在没有反编译Java源代码并自己修改该变量的情况下无法绕过这一点,但幸运的是,在我的应用程序的最终案例中不需要这样做。

答案 1 :(得分:0)

您可以提供自己的

public class Handler extends jdk6.sun.net.www.protocol.http.Handler

通过一些反射,您可以获取HttpURLConnection类的字段,并对其进行修改。

field.setAccessible( true );
field.setBoolean( connection, false );

字段是" tryTransparentNTLMServer"和" tryTransparentNTLMProxy&#34 ;;