2013-02-25 2 views
3

안드로이드에서 NAV 웹 서비스를 사용해야합니다. "Letter"codeunit에 "Upper"기능이 있습니다.안드로이드 네비게이션 웹 서비스

내 PC에 NAV 웹 서비스 (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

안녕하세요 #의 WS를 NAV 서비스를 읽고 안드로이드이 C를 통해 NAV WS와 통신 (NAV 서버가 실행되는 동일한 PC에서 실행, C#을 작성)를 사용하는 것을 시도했다

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을 사용하여 작업을 완료 할 수 있습니다. 코드가 도움이 아래 만약 내가 같은 일을 위해 soap_action을 사용하고 httpclient.getAuthSchemes().register("ntlm", new NTLMSchemeFactory());

1

을 제외하고 pungggi의 대답과 유사 매력처럼 작동, 참조 :

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

+0

그것에 대해 java.net.Authenticator를 사용할 수 있습니다.) –

1

1) 항아리 아래 추가 JCIFS - 1.3. 17.jar ksoap2-안드로이드 조립-3.0.0-항아리 -와 - dependencies.jar이 자바 클래스를 생성)

2 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.자바

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) 비누 구성 비누 요청 보내기 봉투.

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

환영합니다 건배 :) –

관련 문제