AXIS2客户端代码连接C#web service带ntlm认证

搞了两天的AXIS2连接带ntlm认证的web service,要吐血了,百度一堆,不是故作神秘的讲一大堆,就是代码给一半,装吧。。。。

国人就是,知道的不愿意说,说也只说一半,不知道的又装知道,真是气死了。


不得已,问google,不是崇洋媚外,确实国外的程序员比较专业,问的问题无不知无不言的,没有只说一半的,所有的代码,所有的连接全部列得清清楚楚,生怕你做错,所有都罗列的清清楚楚,这个才是真正的技术分享!!!气死我了!不说了,开始分享我的axis2的ntlm认证。


本例是以调用Milestone的web service为例:

1,首先,下载axis2的包,把需要的jar放进自己的project,以下图片显示需要的lib

AXIS2客户端代码连接C#web service带ntlm认证_第1张图片


因为其web services是c#编写,调用需要ntlm认证:

2,用axis2的wsdl2java生成它的class(网上一大把,这里不说了),把生成的java文件放进自己的project。


3,需要用到一个关键的class:JCIFS_NTLMScheme.java


详情链接:http://devsac.blogspot.sg/2010/10/supoprt-for-ntlmv2-with-apache.html

里面有解释和源码,直接copy然后保存成JCIFS_NTLMScheme.java即可。


4,一切都准备好了,开始码code了

代码片段:

		//change the authpolicy use the JCIFS_NTLMScheme.class---httpclient
			AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, JCIFS_NTLMScheme.class);
			
			//create basicAuth
			Authenticator basicAuth = new HttpTransportProperties.Authenticator();			 
			 basicAuth.setDomain(".");
		     basicAuth.setHost("192.168.60.204");
	         basicAuth.setUsername("administrator");  
	         basicAuth.setPassword("password,1"); 
             basicAuth.setPreemptiveAuthentication(false);
             //end create basicAuth
             
             //create webservices client instance
			ServerCommandServiceStub scs=new ServerCommandServiceStub();			
			//Not need this..scs._getServiceClient().getOptions().setUserName("administrator");
			//Not need this..scs._getServiceClient().getOptions().setPassword("password,1");
			
			//create EndpointReference
			//this url 'http://192.168.60.204/ServerAPI/ServerCommandService.asmx?wsdl' is the webservie url that u want to conn
			EndpointReference targetEPR = new EndpointReference("http://192.168.60.204/ServerAPI/ServerCommandService.asmx?wsdl");
			
			//use setTo set the target to client instance's options
			scs._getServiceClient().getOptions().setTo(targetEPR);
			
			//use setProperty set the basicAuth that u created just now for authentiction
			scs._getServiceClient().getOptions().setProperty(HTTPConstants.AUTHENTICATE, basicAuth);
			//*********>>>begin to call the function
			/***************call login function in web service*******************/
			Login log=new Login();
			UUID uid = new UUID(0, 0);
			Guid g=new Guid();
			String testuid=uid.randomUUID().toString();
			System.out.println(testuid);
			g.setGuid(testuid);
			log.setInstanceId(g);
			LoginResponse lr=scs.login(log);
			System.out.println(lr.getLoginResult().getToken());
其中用到JCIFS_NTLMScheme.java,setHost,setDomain,setPassword。。。。等等根据你自己的webservice讯息填入。

project可在我上传的资源中下载,包括所有的java和jar文件

最后奉上JCIFS_NTLMScheme.java的代码,以防个别需要而下载不了(copy一下的代码存成JCIFS_NTLMScheme.java即可):

package com.mediaCommon;

import java.io.IOException;



import org.apache.commons.httpclient.Credentials;

import org.apache.commons.httpclient.HttpMethod;

import org.apache.commons.httpclient.NTCredentials;

import org.apache.commons.httpclient.auth.AuthChallengeParser;

import org.apache.commons.httpclient.auth.AuthScheme;

import org.apache.commons.httpclient.auth.AuthenticationException;

import org.apache.commons.httpclient.auth.InvalidCredentialsException;

import org.apache.commons.httpclient.auth.MalformedChallengeException;



 

/**

 * This is a reimplementation of HTTPClient 3.x's

 * org.apache.commons.httpclient.auth.NTLMScheme.
* It will basically use JCIFS (v1.3.15) in order to provide added support for * NTLMv2 (instead of trying to create its own Type, 2 and 3 messages).
* This class has to be registered manually with HTTPClient before setting * NTCredentials: AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, * JCIFS_NTLMScheme.class);
* Will not work with HttpClient 4.x which requires AuthEngine to be overriden instead of AuthScheme. * * @author Sachin M */ public class JCIFS_NTLMScheme implements AuthScheme { /** NTLM challenge string. */ private String ntlmchallenge = null; private static final int UNINITIATED = 0; private static final int INITIATED = 1; private static final int TYPE1_MSG_GENERATED = 2; private static final int TYPE2_MSG_RECEIVED = 3; private static final int TYPE3_MSG_GENERATED = 4; private static final int FAILED = Integer.MAX_VALUE; /** Authentication process state */ private int state; public JCIFS_NTLMScheme() throws AuthenticationException { // Check if JCIFS is present. If not present, do not proceed. try { Class.forName("jcifs.ntlmssp.NtlmMessage",false,this.getClass().getClassLoader()); } catch (ClassNotFoundException e) { throw new AuthenticationException("Unable to proceed as JCIFS library is not found."); } } public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException { if (this.state == UNINITIATED) { throw new IllegalStateException( "NTLM authentication process has not been initiated"); } NTCredentials ntcredentials = null; try { ntcredentials = (NTCredentials) credentials; } catch (ClassCastException e) { throw new InvalidCredentialsException( "Credentials cannot be used for NTLM authentication: " + credentials.getClass().getName()); } NTLM ntlm = new NTLM(); ntlm.setCredentialCharset(method.getParams().getCredentialCharset()); String response = null; if (this.state == INITIATED || this.state == FAILED) { response = ntlm.generateType1Msg(ntcredentials.getHost(), ntcredentials.getDomain()); this.state = TYPE1_MSG_GENERATED; } else { response = ntlm.generateType3Msg(ntcredentials.getUserName(), ntcredentials.getPassword(), ntcredentials.getHost(), ntcredentials.getDomain(), this.ntlmchallenge); this.state = TYPE3_MSG_GENERATED; } return "NTLM " + response; } public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException { throw new RuntimeException( "Not implemented as it is deprecated anyway in Httpclient 3.x"); } public String getID() { throw new RuntimeException( "Not implemented as it is deprecated anyway in Httpclient 3.x"); } /** * Returns the authentication parameter with the given name, if available. * *

* There are no valid parameters for NTLM authentication so this method * always returns null. *

* * @param name * The name of the parameter to be returned * * @return the parameter with the given name */ public String getParameter(String name) { if (name == null) { throw new IllegalArgumentException("Parameter name may not be null"); } return null; } /** * The concept of an authentication realm is not supported by the NTLM * authentication scheme. Always returns null. * * @return null */ public String getRealm() { return null; } /** * Returns textual designation of the NTLM authentication scheme. * * @return ntlm */ public String getSchemeName() { return "ntlm"; } /** * Tests if the NTLM authentication process has been completed. * * @return true if Basic authorization has been processed, * false otherwise. * * @since 3.0 */ public boolean isComplete() { return this.state == TYPE3_MSG_GENERATED || this.state == FAILED; } /** * Returns true. NTLM authentication scheme is connection based. * * @return true. * * @since 3.0 */ public boolean isConnectionBased() { return true; } /** * Processes the NTLM challenge. * * @param challenge * the challenge string * * @throws MalformedChallengeException * is thrown if the authentication challenge is malformed * * @since 3.0 */ public void processChallenge(final String challenge) throws MalformedChallengeException { String s = AuthChallengeParser.extractScheme(challenge); if (!s.equalsIgnoreCase(getSchemeName())) { throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge); } int i = challenge.indexOf(' '); if (i != -1) { s = challenge.substring(i, challenge.length()); this.ntlmchallenge = s.trim(); this.state = TYPE2_MSG_RECEIVED; } else { this.ntlmchallenge = ""; if (this.state == UNINITIATED) { this.state = INITIATED; } else { this.state = FAILED; } } } private class NTLM { /** Character encoding */ public static final String DEFAULT_CHARSET = "ASCII"; /** * The character was used by 3.x's NTLM to encode the username and * password. Apparently, this is not needed in when passing username, * password from NTCredentials to the JCIFS library */ private String credentialCharset = DEFAULT_CHARSET; void setCredentialCharset(String credentialCharset) { this.credentialCharset = credentialCharset; } private String generateType1Msg(String host, String domain) { jcifs.ntlmssp.Type1Message t1m = new jcifs.ntlmssp.Type1Message(jcifs.ntlmssp.Type1Message.getDefaultFlags(), domain, host); return jcifs.util.Base64.encode(t1m.toByteArray()); } private String generateType3Msg(String username, String password, String host, String domain, String challenge) { jcifs.ntlmssp.Type2Message t2m; try { t2m = new jcifs.ntlmssp.Type2Message(jcifs.util.Base64.decode(challenge)); } catch (IOException e) { throw new RuntimeException("Invalid Type2 message", e); } jcifs.ntlmssp.Type3Message t3m = new jcifs.ntlmssp.Type3Message(t2m, password, domain, username, host, 0); return jcifs.util.Base64.encode(t3m.toByteArray()); } } }



你可能感兴趣的:(AXIS2客户端代码连接C#web service带ntlm认证)