2013-02-25 108 views
3

我需要使用android的NAV web服務。 我得到了具有「上」功能的「字母」代碼單元。android使用navision web服務

我在PC上設置了NAV Web服務(NTLM身份驗證)並關閉了防火牆(以便此服務在我的網絡中的其他設備上可見)。輸入登錄/密碼(我的PC帳戶)後,可以在瀏覽器(也可以在adroid設備上)訪問該服務。 如果我使用this code它與END_DOCUMENT空異常的「調用」崩潰... 是因爲身份驗證?

如果我使用此代碼連接

HttpGet request = new 
HttpGet("http://[myPC'sIP]:7047/DynamicsNAV/WS/SystemService"); 
HttpResponse response = client.execute(request); 

我得到401錯誤,而只是指定IP

HttpGet request = new HttpGet("http://[myPC'sIP]"); 
HttpResponse response = client.execute(request); 

返回代碼200(OK) 我怎樣才能發送憑證?我嘗試了幾種方法,但結果總是一樣的... 您是否有這個問題的經驗?

回答

0

通過創建另一個Web Service的解決(寫在C#,其中NAV服務器運行在同一臺PC上運行)讀取導航服務和Android通過該C與NAV WS通信#WS

0

嗨你有沒有嘗試過用

var httpClient = new DefaultHttpClient(); 
NTCredentials nt = new NTCredentials("user", "pass", "", "domain"); 
httpClient.GetCredentialsProvider().SetCredentials(AuthScope.ANY, nt); 
0

這是http認證是如何supposed to work。你可以使用提琴手來看看你的中介正在做什麼。如果你想擺脫它,你將不得不做同樣的事情:)

那被稱爲與Navision認證是沒有野餐,因爲它使用SPNEGO或NTLM。如果您可以配置NTLM,則可以使用android-ntlm完成工作。類似於pungggi的回答除了httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());

1

我用soap_action做同樣及其工作般的魅力,看看下面的代碼可以幫助你:

String namespace = "urn:microsoft-dynamics-schemas/codeunit/NavisionWS"; 
String url = "http://IP:7047/DynamicsNAV/WS/Codeunit/NavisionWS"; 
String soap_action = "urn:microsoft-dynamics-schemas/codeunit/NavisionWS:GetLoginInfo"; 
String method_name = "GetLoginInfo"; 
try 
     { 
       SoapObject request = new SoapObject(namespace, method_name);  
       SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 

       envelope.dotNet = true; 
       envelope.setOutputSoapObject(request); 
       HttpTransportSE transport = new HttpTransportSE(url);  
       transport.call(soap_action, envelope); // Receive Error here! 
        SoapObject result = (SoapObject) envelope.getResponse(); 
        great = result.toString(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
       great = e.toString(); 
       Toast.makeText(this, great, Toast.LENGTH_LONG).show(); 
     } 
+0

但它不請求登錄/傳遞?當您在瀏覽器中輸入「http:// IP:7037/DynamicsNAV/WS/SystemService」時,它會要求我提供憑據...您的NAV服務器在哪個帳戶下運行? – user1390456 2013-09-25 12:50:09

+0

您可以使用java.net.Authenticator;) – 2013-11-28 19:10:58

1

1)添加下面瓶 JCIFS-1.3。 17.jar ksoap2-機器人組裝-3.0.0-罐與 - dependencies.jar

2)創建這些Java類 JCIFSEngine.java

package com.demo.Authentication; 
import jcifs.ntlmssp.NtlmFlags; 
import jcifs.ntlmssp.Type1Message; 
import jcifs.ntlmssp.Type2Message; 
import jcifs.ntlmssp.Type3Message; 
import jcifs.util.Base64; 
import org.apache.http.impl.auth.NTLMEngine; 
import org.apache.http.impl.auth.NTLMEngineException; 

import java.io.IOException; 

/** 
* Class taken from http://hc.apache.org/httpcomponents-client-ga/ntlm.html 
*/ 
public final class JCIFSEngine implements NTLMEngine { 

    private static final int TYPE_1_FLAGS = 
      NtlmFlags.NTLMSSP_NEGOTIATE_56 | 
      NtlmFlags.NTLMSSP_NEGOTIATE_128 | 
      NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 | 
      NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | 
      NtlmFlags.NTLMSSP_REQUEST_TARGET; 

    public String generateType1Msg(final String domain, final String workstation) 
      throws NTLMEngineException { 
     final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation); 
     return Base64.encode(type1Message.toByteArray()); 
    } 

    public String generateType3Msg(final String username, final String password, 
      final String domain, final String workstation, final String challenge) 
      throws NTLMEngineException { 
     Type2Message type2Message; 
     try { 
      type2Message = new Type2Message(Base64.decode(challenge)); 
     } catch (final IOException exception) { 
      throw new NTLMEngineException("Invalid NTLM type 2 message", exception); 
     } 
     final int type2Flags = type2Message.getFlags(); 
     final int type3Flags = type2Flags 
       & (0xffffffff^(NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER)); 
     final Type3Message type3Message = new Type3Message(type2Message, password, domain, 
       username, workstation, type3Flags); 
     return Base64.encode(type3Message.toByteArray()); 
    } 
} 

NtlmTransport。的java

package com.demo.Authentication; 

import java.io.File; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.Arrays; 
import java.util.List; 
import org.apache.http.Header; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.auth.AuthScheme; 
import org.apache.http.auth.AuthSchemeFactory; 
import org.apache.http.auth.AuthScope; 
import org.apache.http.auth.NTCredentials; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.ByteArrayEntity; 
import org.apache.http.impl.auth.NTLMScheme; 
import org.apache.http.impl.client.AbstractHttpClient; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.params.HttpParams; 
import org.apache.http.protocol.BasicHttpContext; 
import org.apache.http.protocol.HttpContext; 
import org.ksoap2.HeaderProperty; 
import org.ksoap2.SoapEnvelope; 
import org.ksoap2.serialization.SoapSerializationEnvelope; 
import org.ksoap2.transport.ServiceConnection; 
import org.ksoap2.transport.Transport; 
import org.xmlpull.v1.XmlPullParserException; 


public class NtlmTransport extends Transport { 

    static final String ENCODING = "utf-8"; 

    private final DefaultHttpClient client = new DefaultHttpClient(); 
    private final HttpContext localContext = new BasicHttpContext(); 
    private String urlString; 
    private String user; 
    private String password; 
    private String ntDomain; 
    private String ntWorkstation; 
    public static String AuthenticationCode; 

    public NtlmTransport(String url, String user, String password, 
      String domain, String workStation) { 
this.urlString = url; 
this.user = user; 
this.password = password; 
this.ntDomain = domain; 
this.ntWorkstation = workStation; 

} 

    public void setCredentials(String url, String user, String password, 
           String domain, String workStation) { 
     this.urlString = url; 
     this.user = user; 
     this.password = password; 
     this.ntDomain = domain; 
     this.ntWorkstation = workStation; 

    } 

    public List call(String targetNamespace, SoapEnvelope envelope, List headers) 
      throws IOException, XmlPullParserException { 
     return call(targetNamespace, envelope, headers, null); 
    } 

    public List call(String soapAction, SoapEnvelope envelope, List headers, File outputFile) 
      throws IOException, XmlPullParserException { 
     if (outputFile != null) { 
      // implemented in HttpTransportSE if you are willing to port.. 
      throw new RuntimeException("Writing to file not supported"); 
     } 
     HttpResponse resp = null; 

     setupNtlm(urlString, user, password); 

     try { 
      // URL url = new URL(urlString); 
      HttpPost httppost = new HttpPost(urlString); 

      setHeaders(soapAction, envelope, httppost, headers); 

      resp = client.execute(httppost, localContext); 
      HttpEntity respEntity = resp.getEntity(); 


      InputStream is = respEntity.getContent(); 
      parseResponse(envelope, is); 

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

     System.out.println("RESPONSE STATUS CODE :"+resp.getStatusLine().getStatusCode()); 
     if (resp != null) { 
      return Arrays.asList(resp.getAllHeaders()); 
     } else { 
      return null; 
     } 
    } 

    private void setHeaders(String soapAction, SoapEnvelope envelope, HttpPost httppost, List headers) { 
     byte[] requestData = null; 
     try { 
      requestData = createRequestData(envelope); 
     } catch (IOException iOException) { 
     } 
     ByteArrayEntity byteArrayEntity = new ByteArrayEntity(requestData); 
     httppost.setEntity(byteArrayEntity); 
     httppost.addHeader("User-Agent", org.ksoap2.transport.Transport.USER_AGENT); 
     // SOAPAction is not a valid header for VER12 so do not add 
     // it 
     // @see "http://code.google.com/p/ksoap2-android/issues/detail?id=67 
     if (envelope.version != SoapSerializationEnvelope.VER12) { 
      httppost.addHeader("SOAPAction", soapAction); 
     } 

     if (envelope.version == SoapSerializationEnvelope.VER12) { 
      httppost.addHeader("Content-Type", Transport.CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8); 
     } else { 
      httppost.addHeader("Content-Type", Transport.CONTENT_TYPE_XML_CHARSET_UTF_8); 
     } 

     // Pass the headers provided by the user along with the call 
     if (headers != null) { 
      for (int i = 0; i < headers.size(); i++) { 
       HeaderProperty hp = (HeaderProperty) headers.get(i); 
       httppost.addHeader(hp.getKey(), hp.getValue()); 
      } 
     } 
    } 


    // Try to execute a cheap method first. This will trigger NTLM authentication 
    public void setupNtlm(String dummyUrl, String userId, String password) { 
     try { 

      ((AbstractHttpClient) client).getAuthSchemes().register("ntlm", new NTLMSchemeFactory()); 

      NTCredentials creds = new NTCredentials(userId, password, ntWorkstation, ntDomain); 
      client.getCredentialsProvider().setCredentials(AuthScope.ANY, creds); 

      HttpGet httpget = new HttpGet(dummyUrl); 

      HttpResponse response1 = client.execute(httpget, localContext); 
      HttpEntity entity1 = response1.getEntity(); 
      Header[] hArray = response1.getAllHeaders(); 
      int size = hArray.length; 
      AuthenticationCode = String.valueOf(response1.getStatusLine().getStatusCode()); 
      System.out.println("AUTHENTICATION STATUS CODE :"+response1.getStatusLine().getStatusCode()); 
      /* for (int i = 0; i < size; i ++) { 
       Header h = hArray[i]; 
       if (h.getName().equals("WWW-Authenticate")) { 
        entity1.consumeContent(); 
        throw new Exception("Failed Authentication"); 
       } 
      }*/ 

      entity1.consumeContent(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

     //NTLM Scheme factory 
    private class NTLMSchemeFactory implements AuthSchemeFactory { 
     public AuthScheme newInstance(final HttpParams params) { 
     // see http://www.robertkuzma.com/2011/07/ 
     // manipulating-sharepoint-list-items-with-android-java-and-ntlm-authentication/ 
      return new NTLMScheme(new JCIFSEngine()); 
     } 
    } 

    public ServiceConnection getServiceConnection() throws IOException 
    { 
     throw new IOException("Not using ServiceConnection in transport"); 
    } 

    public String getHost() { 
     String retVal = null; 
     try { 
      retVal = new URL(url).getHost(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 
     return retVal; 
    } 

    public int getPort() { 
     int retVal = -1; 
     try { 
      retVal = new URL(url).getPort(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 
     return retVal; 
    } 

    public String getPath() { 
     String retVal = null; 
     try { 
      retVal = new URL(url).getPath(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 
     return retVal; 
    } 
} 

3) 調用此方法與paramater URL, 「用戶名」, 「口令」, 「則domainName」, 「的SystemName」

NtlmTransport ntlm = new NtlmTransport(url, "username", "password", "domainName","SystemName"); 

4)發送SOAP請求,其由肥皂的信封。

ntlm.call("namespace/methodname", soapEnvelope); 
+0

歡迎來到Cheers :) – 2014-04-23 04:56:13