2011-02-01 17 views
13

मैं JAX-WS के माध्यम से एक शेयरप्वाइंट सूची का उपयोग करने के रूप में वर्णित किया hereJAX-WS शेयरप्वाइंट 401 अनधिकृत NTLM

कोशिश हालांकि, जब कोड चल नीचे मैं:

java.lang.Exception: Exception. See stacktrace.com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized 

शेयरप्वाइंट NTLM प्रमाणीकरण की आवश्यकता है। समस्या क्या हो सकती है? आपका बहुत बहुत धन्यवाद!

public static ListsSoap sharePointListsAuth(String userName, String password) throws Exception { 
    ListsSoap port = null; 
    if (userName != null && password != null) { 
     try { 
      Lists service = new Lists(); 
      port = service.getListsSoap(); 
      System.out.println("Web Service Auth Username: " + userName); 
      ((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; 
} 

उत्तर

17

जब Exchange वेब सेवाओं के लिए JAX-WS के साथ जोड़ने मैं एक ही समस्या का सामना करना पड़ रहा था, और यहाँ क्या मेरे लिए काम किया है:

सबसे पहले, एक प्रमाणक बनाएँ:

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

public class NtlmAuthenticator extends Authenticator { 

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

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

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

में अपने एप्लिकेशन, प्रमाणीकरणकर्ता को डिफ़ॉल्ट के रूप में सेट करें:

String username = "DOMAIN\\USERNAME"; 
String password = "PASSWORD" 

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

ध्यान दें कि मैं विधि # 2 का उपयोग कर रहा हूं Java documentation.

+0

क्या यह केवल पूरे एप्लिकेशन के लिए सेटअप है? अगर मुझे उस क्रेडेंशियल्स के साथ केवल विशेष अनुरोध प्रमाणित करने की आवश्यकता है तो क्या होगा? – glaz666

+0

आप बता सकते हैं कि कौन सा URL आपके कस्टम प्रमाणीकरण वर्ग के अंदर getRequestingURL() के साथ प्रमाण-पत्रों का अनुरोध कर रहा है। तो, आप तदनुसार प्रमाण पत्र वापस कर सकते हैं। – jmend

+0

@MarcelLevy - आपके द्वारा प्रदान किया गया कोड ओपी के प्रश्न में कोड के साथ कहां फिट है? आपके द्वारा प्रदान किया गया लिंक अब मृत है ... – Joe

1

में वर्णित के रूप जहाँ तक मुझे पता के रूप में डोमेन निर्दिष्ट करने के लिए, आप BindingProvider के माध्यम से NTLM प्रमाणीकरण नहीं कर सकते।

यदि आप स्प्रिंग फ्रेमवर्क से परिचित हैं, तो आप Spring-WS का उपयोग कर सकते हैं। स्प्रिंग-डब्ल्यूएस Apache HttpClient 4.x के साथ HttpComponentsMessageSender क्लास के माध्यम से परिवहन का समर्थन करता है। अपाचे एचटीपी क्लाइंट 4.x एनटीएलएम प्रमाणीकरण के लिए अच्छा समर्थन है। आप wsimport टूल द्वारा उत्पन्न जेएक्स-डब्ल्यूएस कक्षाओं का उपयोग marshalSendAndReceive पर तर्क के रूप में कर सकते हैं।

2

मेरी शिक्षाओं के आधार पर, बाइंडिंगप्रोवाइडर पैरामीटर को ओवरराइड करना आवश्यक उपयोगकर्ता नाम और पासवर्ड सेट नहीं करता है। यह साबित करने का सबसे आसान तरीका यह है कि बीपी ओवरराइड के माध्यम से डोमेन नाम पारित करने का कोई तरीका नहीं है।

मैंने इंटरनेट पर कई पोस्ट देखी हैं जो एनटीएलएम प्रमाणीकरण उदाहरण (जिसे ओरेकल से उपलब्ध जावा 6 दस्तावेज के अनुसार परिभाषित किया गया है) का उपयोग करने के लिए ऊपर मार्सेल लेवी के सुझाव के समान तरीका सुझाता है। लेकिन, यह समाधान मेरे लिए काम नहीं करता था (मैं किसी भी अनुप्रयोग सर्वर तर्क से स्वतंत्र एक स्टैंडअलोन प्रोग्राम विकसित कर रहा था)।

मैं googled और इस समस्या के समाधान का एक बहुत कोशिश की .. जाहिरा तौर पर सबसे सरल कोड है कि काम किया JCIFS पुस्तकालय

//Set the jcifs properties 
    jcifs.Config.setProperty("jcifs.smb.client.domain", "domainname"); 
    jcifs.Config.setProperty("jcifs.netbios.wins", "xxx.xxx.xxx.xxx"); 
    jcifs.Config.setProperty("jcifs.smb.client.soTimeout", "300000"); // 5 minutes 
    jcifs.Config.setProperty("jcifs.netbios.cachePolicy", "1200"); // 20 minutes 
    jcifs.Config.setProperty("jcifs.smb.client.username", "username"); 
    jcifs.Config.setProperty("jcifs.smb.client.password", "password"); 

    //Register the jcifs URL handler to enable NTLM 
    jcifs.Config.registerSmbURLHandler(); 

जाहिर CXF 3.0 does not को विन्यस्त करने का एक मान्य तरीका है का उपयोग कर नीचे के रूप में है HTTP क्लाइंट (4.3.x) NTCredentials उदाहरण के साथ। NTCredentials साथ बग https://issues.apache.org/jira/browse/CXF-5671


को देखें वैसे, अगर आप एक सरल संदेश है जो प्रेषित किए जाने की जरूरत है, बस HTTP क्लाइंट का उपयोग करें (मैं 4.3.4 का उपयोग कर काम किया .. पहले के संस्करणों के बारे में सुनिश्चित नहीं) उदाहरण। उसने भी मेरे लिए जादू किया .. नमूना नीचे जैसा है:

final NTCredentials ntCredentials = new NTCredentials("username", "Passworrd","destination", "domain"); 
    CredentialsProvider credsProvider = new BasicCredentialsProvider(); 

    credsProvider.setCredentials(AuthScope.ANY, ntCredentials); 
    CloseableHttpClient httpclient = HttpClientBuilder.create() 
             .setDefaultCredentialsProvider(credsProvider) 
             .build(); 
संबंधित मुद्दे