2012-06-22 143 views
2

所以我试图用NTLMv2和Java来追踪一个奇怪的错误。似乎NTLM忽略了我在基于Java的身份验证过程中传递的任何信息,并在其他位置找到信息。因此,即使我提供了错误的信息,NTLM也会在我的机器上进行身份验证,即使提供了正确的信息,NTLM也不能在任何其他机器上工作。如果相关,端点是MOSS 2007 web服务API。验证Java中的NTLMv2身份验证

下面是我使用验证过程:

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信息,并使用它来代替所提供的信息,但我不知道在什么时候会发生。

+0

我已经使用Wireshark来确认连接确实是使用NTLM创建的,并且在标准的3步NTLM过程中没有任何问题进行身份验证,即使给定的用户名/密码不正确。 – WLPhoenix

回答

1

看来问题是基于Java的“单点登录”功能。因为我在Windows计算机上尝试NTLM身份验证,所以Java具有默认为当前帐户登录信息的硬编码值,只有在失败时才使用Java身份验证器。

似乎没有办法绕过这个,没有反编译Java源代码并自己修改那个变量,但幸好在我的应用程序的最终情况下不需要。

+1

有一种方法可以更改代码,但它不适用于生产 http://stackoverflow.com/a/9024765/14811 –

0

您可以提供自己的

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

与一些反映你可以得到HttpURLConnection类类的字段,并对其进行修改。

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

该字段是“tryTransparentNTLMServer”和“tryTransparentNTLMProxy”;