我使用axis2创建客户端代码并使用NTLM身份验证访问wcf webservice。我的客户端代码是
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);
当我运行客户端代码时,它返回以下错误
org.apache.axis2.AxisFault: Transport error: 401 Error: Unauthorized
at org.apache.axis2.transport.http.HTTPSender.handleResponse(HTTPSender.java:310)
at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:194)
at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:404)
at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:231)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.tempuri.Service1Stub.welcomeData(Service1Stub.java:473)
at ws.client.Client.myservice(Client.java:159)
at ws.client.Client.main(Client.java:50)
我的标题日志是
>> "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]
我不知道我犯了什么错误。
答案 0 :(得分:1)
据我所知,Axis2 1.6的标准版本仍然使用HTTPClient 3.1和NTLMv1,大多数Windows服务器默认禁用它们。更改此设置需要修补Axis2或更改服务器上的注册表设置。
这是一个开发线程的链接,其中包含最近25-05-2012的补丁:
https://issues.apache.org/jira/browse/AXIS2-4318
答案 1 :(得分:1)
不确定您是否已找到通过NTLM身份验证访问WCF的方法..但这是我为解决此问题所做的工作..
HttpClient不支持NTLM v2因此我使用JCIFS库返回NTLM v1,2,3消息类型,如本网站所述
http://devsac.blogspot.com/2010/10/supoprt-for-ntlmv2-with-apache.html
我刚刚使用上述网站上的JCIFS_NTLMScheme.java文件注册了auth方案,它确实有效!!!!
示例客户端:
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);
答案 2 :(得分:0)
正如@WLPhoenix指出的那样,Axis2使用旧的Apache Commons HTTP,它只支持旧的反向工程NTLM实现。在新的Apache HTTPComponents 4.2.3中,为新的,公开记录的NTLM标准添加了支持,该标准适用于较新版本的Windows Server和IIS (source)。
这是一种使用自定义Apache Commons HTTP AuthScheme向新的Apache HTTPComponents 4 NTLMScheme反向移植以在Axis2中使用的方法。
public class BackportedNTLMScheme extends org.apache.http.impl.auth.NTLMScheme implements org.apache.commons.httpclient.auth.AuthScheme {
@Override
public String authenticate(final Credentials credentials, final HttpMethod method) throws AuthenticationException {
org.apache.commons.httpclient.NTCredentials oldCredentials;
try {
oldCredentials = (org.apache.commons.httpclient.NTCredentials) credentials;
} catch (final ClassCastException e) {
throw new InvalidCredentialsException(
"Credentials cannot be used for NTLM authentication: "
+ credentials.getClass().getName());
}
final org.apache.http.auth.Credentials adaptedCredentials = new NTCredentials(oldCredentials.getUserName(), oldCredentials.getPassword(), oldCredentials.getHost(), oldCredentials.getDomain());
try {
final Header header = super.authenticate(adaptedCredentials, null);
return header.getValue();
} catch (final org.apache.http.auth.AuthenticationException e) {
throw new AuthenticationException("AuthenticationException", e);
}
}
@Override
public void processChallenge(final String challenge) throws MalformedChallengeException {
final String s = AuthChallengeParser.extractScheme(challenge);
if (!s.equalsIgnoreCase(getSchemeName())) {
throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge);
}
int challengeIdx = challenge.indexOf(' ');
final CharArrayBuffer challengeBuffer;
if(challengeIdx != -1){
challengeBuffer = new CharArrayBuffer(challenge.length());
challengeBuffer.append(challenge);
} else {
challengeBuffer = new CharArrayBuffer(0);
challengeIdx = 0;
}
try {
parseChallenge(challengeBuffer, challengeIdx, challengeBuffer.length());
} catch (final org.apache.http.auth.MalformedChallengeException e) {
throw new MalformedChallengeException("MalformedChallengeException", e);
}
}
@Override
@Deprecated
public String getID() {
throw new RuntimeException("deprecated BackportedNTLMScheme.getID()");
}
@Override
@Deprecated
public String authenticate(final Credentials credentials, final String method, final String uri) throws AuthenticationException {
throw new RuntimeException("deprecated BackportedNTLMScheme.authenticate(Credentials, String, String)");
}
}
// given a stubbed AXIS SOAP client called MyAxisClient:
MyAxisClientStub myAxisClient = new MyAxisClientStub();
ServiceClient serviceClient = myAxisClient._getServiceClient();
// use new NTLM
AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, BackportedNTLMScheme.class);
Authenticator authenticator = new Authenticator();
authenticator.setAuthSchemes(Arrays.asList(AuthPolicy.NTLM));
authenticator.setDomain("my-auth-domain");
authenticator.setHost("my-auth-host");
authenticator.setUsername("my-username");
authenticator.setPassword("my-password");
serviceClient.getOptions().setProperty(HTTPConstants.AUTHENTICATE, authenticator);
//call MyAxisClient methods
我在Windows Server 2008 R2上的IIS 7.5上进行了测试。
答案 3 :(得分:0)
直到同事发现修复了 401 Unauthorized 的问题,我才能让它工作。
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);