axis2客户端中的NTLM身份验证返回错误401

axis2客户端中的NTLM身份验证返回错误401,axis2,Axis2,我正在使用axis2创建客户端代码,并通过NTLM身份验证访问wcf Web服务。我的客户代码是 Service1Stub stub = new Service1Stub(); Options options = stub._getServiceClient().getOptions(); HttpTransportProperties.Authenticator auth = new HttpTransportProperties.

我正在使用axis2创建客户端代码,并通过NTLM身份验证访问wcf Web服务。我的客户代码是

    Service1Stub stub = new Service1Stub();             
    Options options = stub._getServiceClient().getOptions();    
    HttpTransportProperties.Authenticator   auth = new HttpTransportProperties.Authenticator();
    auth.setUsername("administrator");
    auth.setPassword("passwrd");
    auth.setHost("172.16.12.25"); 
    auth.setDomain("MY-PC");        
    List<String> authSchemes = new ArrayList<String>();         
    authSchemes.add(HttpTransportProperties.Authenticator.NTLM);        
    auth.setAuthSchemes(authSchemes); 

    options.setProperty(HTTPConstants.AUTHENTICATE, auth); 
    options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE); 
    stub._getServiceClient().setOptions(options); 
我的头日志是

     >> "POST /Service1/Service1.svc HTTP/1.1[\r][\n]"
     >> "Content-Type: text/xml; charset=UTF-8[\r][\n]"
     >> "SOAPAction: "http://tempuri.org/IService1/WelcomeData"[\r][\n]"
     >> "User-Agent: Axis2[\r][\n]"
     >> "Content-Length: 278[\r][\n]"
     >> "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGMAAAAAAAAAewAAAAkACQBAAAAADQANAEkAAAANAA0AVgAAAAAAAAB7AAAABlIAAFZJTk9USC1QQ0FETUlOSVNUUkFUT1IxNzIuMTYuMTIuMjQ11kmkEIwyUVitHBvTPwhExpcylZ9vkdwd[\r][\n]"
     >> "Host: 172.16.12.25[\r][\n]"
     >> "[\r][\n]"
     >> "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns1:WelcomeData xmlns:ns1="http://tempuri.org/"><ns1:helloservice>Hello Servie</ns1:helloservice></ns1:WelcomeData></soapenv:Body></soapenv:Envelope>"
     << "HTTP/1.1 401 Unauthorized[\r][\n]"
     << "HTTP/1.1 401 Unauthorized[\r][\n]"
     << "Content-Type: text/html[\r][\n]"
     << "Server: Microsoft-IIS/7.5[\r][\n]"
     << "WWW-Authenticate: NTLM[\r][\n]"
     << "X-Powered-By: ASP.NET[\r][\n]"
     << "Date: Thu, 10 May 2012 19:30:20 GMT[\r][\n]"
     << "Content-Length: 1293[\r][\n]"
     << "[\r][\n]"
     << "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">[\r][\n]"
     << "<html xmlns="http://www.w3.org/1999/xhtml">[\r][\n]"
     << "<head>[\r][\n]"
     << "<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>[\r][\n]"
     << "<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>[\r][\n]"
     << "<style type="text/css">[\r][\n]"
     << "<!--[\r][\n]"
     << "body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}[\r][\n]"
     << "fieldset{padding:0 15px 10px 15px;} [\r][\n]"
     << "h1{font-size:2.4em;margin:0;color:#FFF;}[\r][\n]"
     << "h2{font-size:1.7em;margin:0;color:#CC0000;} [\r][\n]"
     << "h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} [\r][\n]"
     << "#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;[\r][\n]"
     << "background-color:#555555;}[\r][\n]"
     << "#content{margin:0 0 0 2%;position:relative;}[\r][\n]"
     << ".content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}[\r][\n]"
     << "-->[\r][\n]"
     << "</style>[\r][\n]"
     << "</head>[\r][\n]"
     << "<body>[\r][\n]"
     << "<div id="header"><h1>Server Error</h1></div>[\r][\n]"
     << "<div id="content">[\r][\n]"
     << " <div cla"
     << "ss="content-container"><fieldset>[\r][\n]"
     << "  <h2>401 - Unauthorized: Access is denied due to invalid credentials.</h2>[\r][\n]"
     << "  <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>[\r][\n]"
     << " </fieldset></div>[\r][\n]"
     << "</div>[\r][\n]"
     << "</body>[\r][\n]"
     << "</html>[\r][\n]
>“POST/Service1/Service1.svc HTTP/1.1[\r][\n]”
>>“内容类型:text/xml;字符集=UTF-8[\r][\n]”
>>“SOAPAction:”http://tempuri.org/IService1/WelcomeData“[\r][\n]”
>>“用户代理:Axis2[\r][\n]”
>>“内容长度:278[\r][\n]”
>>“授权:NTLM TlrmtVtuaaaaaaaagayagmaaaaaaaaaaaaaaaaaqaaaaaaaaaaaaaaaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>>“主机:172.16.12.25[\r][\n]”
>>“[\r][\n]”
>>“你好,塞维”

据我所知,Axis2 1.6的标准版本仍然使用HTTPClient 3.1和NTLMv1,大多数Windows服务器默认情况下都禁用了NTLMv1。更改此设置需要修补Axis2或更改服务器上的注册表设置

这里有一个到开发线程的链接,最近的补丁是2012年5月25日:

不确定您是否找到了通过NTLM身份验证访问WCF的方法。。但这就是我为解决这个问题所做的

HttpClient不支持NTLM v2,因此我使用JCIFS库返回NTLM v1,2,3消息类型,如本网站所述

我刚刚使用了上面网站上的JCIFS_NTLMScheme.java文件来注册身份验证方案,它成功了

示例客户端:

    List authSchema = new ArrayList();
    AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, org.tempuri.JCIFS_NTLMScheme.class);
    HttpTransportProperties.Authenticator auth = new HttpTransportProperties.Authenticator();
    auth.setUsername("");
    auth.setPassword("");
    auth.setDomain("");
    auth.setHost("");
    auth.setPort();
    List authPrefs = new ArrayList(1);
    authPrefs.add(AuthPolicy.NTLM);
    auth.setAuthSchemes(authPrefs);
    stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth); 

正如@WLPhoenix所指出的,Axis2使用旧的Apache Commons HTTP,它只支持旧的、反向工程的NTLM实现。在新的ApacheHttpComponents 4.2.3中,添加了对新的、公开记录的NTLM标准的支持,该标准适用于较新版本的Windows Server和IIS

下面是一种使用自定义Apache Commons HTTP AuthScheme将新的Apache HTTPComponents 4 NTLMScheme向后移植到Axis2中的方法

public类BackportedNTLMScheme扩展org.apache.http.impl.auth.NTLMScheme实现org.apache.commons.httpclient.auth.AuthScheme{
@凌驾
公共字符串身份验证(最终凭据、最终HttpMethod方法)引发AuthenticationException{
org.apache.commons.httpclient.NTCredentials;
试一试{
oldCredentials=(org.apache.commons.httpclient.NTCredentials)凭证;
}捕获(最终类CastException e){
抛出新的InvalidCredentialsException(
“凭据不能用于NTLM身份验证:”
+credentials.getClass().getName());
}
final org.apache.http.auth.Credentials adaptedCredentials=新的NTCredentials(oldCredentials.getUserName()、oldCredentials.getPassword()、oldCredentials.getHost()、oldCredentials.getDomain());
试一试{
final Header=super.authenticate(adaptedCredentials,null);
返回header.getValue();
}捕获(最终org.apache.http.auth.AuthenticationException e){
抛出新的AuthenticationException(“AuthenticationException”,e);
}
}
@凌驾
public void processChallenge(最终字符串质询)引发格式错误的质询异常{
最终字符串s=AuthChallengeParser.extractScheme(质询);
如果(!s.equalsIgnoreCase(getSchemeName())){
抛出新的畸形挑战异常(“无效NTLM挑战:+挑战”);
}
int challengedx=challenge.indexOf(“”);
最终特征缓冲挑战缓冲;
if(challengeIdx!=-1){
challengeBuffer=newcharlarraybuffer(challenge.length());
challengeBuffer.append(challenge);
}否则{
challengeBuffer=新字符缓冲区(0);
challengedX=0;
}
试一试{
parseChallenge(challengeBuffer,challengeIdx,challengeBuffer.length());
}捕获(最终org.apache.http.auth.MalformedChallenge异常){
抛出新的MalformedChallengeException(“MalformedChallengeException”,e);
}
}
@凌驾
@不赞成
公共字符串getID(){
抛出新的RuntimeException(“不推荐的BackportedNTLMScheme.getID()”;
}
@凌驾
@不赞成
公共字符串身份验证(最终凭据凭据、最终字符串方法、最终字符串uri)引发AuthenticationException{
抛出新的RuntimeException(“不推荐的BackportedNTLMScheme.authenticate(凭据、字符串、字符串)”);
}
}
用法
//给定一个名为MyAxisClient的存根式AXIS SOAP客户端:
MyAxisClientStub myAxisClient=新建MyAxisClientStub();
ServiceClient ServiceClient=myAxisClient.\u getServiceClient();
//使用新的NTLM
registerAuthScheme(AuthPolicy.NTLM,BackportedNTLMScheme.class);
验证器验证器=新验证器();
setAuthSchemes(Arrays.asList(AuthPolicy.NTLM));
setDomain(“我的身份验证域”);
setHost(“我的身份验证主机”);
authenticator.setUsername(“我的用户名”);
authenticator.setPassword(“我的密码”);
serviceClient.getOptions().setProperty(HTTPConstants.AUTHENTICATE,authenticator);
//调用MyAxisClient方法

我在Windows Server 2008 R2上的IIS 7.5上对此进行了测试。

在一位同事找到修复此问题的方法之前,我无法使其正常工作

import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
import org.apache.commons.httpclient.auth.CredentialsProvider;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.NTCredentials;

final NTCredentials credentials = new NTCredentials(username, password, host, domain);    
final CredentialsProvider myCredentialsProvider = new CredentialsProvider() {
        public Credentials getCredentials(final AuthScheme scheme, final String host, int port, boolean proxy) throws CredentialsNotAvailableException {
            return credentials;
        }
    };

    DefaultHttpParams.getDefaultParams().setParameter("http.authentication.credential-provider", myCredentialsProvider);

大家好,我也面临同样的问题,我应该把这个类放在哪里,或者如何将ApacheHttpComponents 4与AXIS集成?Thanks@Haobo我已经扩展了用法部分。您可以将该类放在项目中的任何位置,只要在发出SOAP请求之前在
AuthPolicy.registerAuthScheme()中引用它。非常感谢!我试图应用您发布的代码,唯一的问题是“MyAxisClient MyAxisClient=new MyAxisClientStub();”,eclipse无法解析MyAxisClientStub,您知道吗?谢谢我假设MyAxisClient是AXIS客户端的类,尝试了我的类,仍然无法解析_getServiceClient()S
import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
import org.apache.commons.httpclient.auth.CredentialsProvider;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.NTCredentials;

final NTCredentials credentials = new NTCredentials(username, password, host, domain);    
final CredentialsProvider myCredentialsProvider = new CredentialsProvider() {
        public Credentials getCredentials(final AuthScheme scheme, final String host, int port, boolean proxy) throws CredentialsNotAvailableException {
            return credentials;
        }
    };

    DefaultHttpParams.getDefaultParams().setParameter("http.authentication.credential-provider", myCredentialsProvider);