axis2客户端NTLM身份验证

时间:2011-05-03 05:46:25

标签: java web-services iis axis2 axis

我有一个需要使用IIS进行Kerberos / NTLM身份验证的axis2(v1.5.3)客户端。我怎样才能做到这一点?这是我现在的代码,它失败了401 - unauthorized错误:

List<String> authScheme = new ArrayList<String>();
authScheme.add(HttpTransportProperties.Authenticator.NTLM);
HttpTransportProperties.Authenticator ntlm =
                 new HttpTransportProperties.Authenticator();
ntlm.setAuthSchemes(authScheme);
ntlm.setUsername("Administrator");
ntlm.setPassword("password");
ntlm.setHost("http://server/_vti_bin/someservice.asmx");
ntlm.setPort(80);
ntlm.setDomain("server_domain");
Options options = webs._getServiceClient().getOptions();
options.setProperty(HTTPConstants.AUTHENTICATE, ntlm);
stub._getServiceClient().setOptions(options);  

使用C#编写的客户端可以正常使用相同的身份验证设置:

CredentialCache myCache = new CredentialCache();            
myCache.Add(new Uri(webs.Url), "NTLM", 
            new NetworkCredential("Administrator", "password", "server_domain"));
stub.Credentials = myCache;

4 个答案:

答案 0 :(得分:3)

AXIS2中的NTLM存在问题。它以ntlm.setHost()方法为中心。此处的条目在NTLM交换中用作WORKSTATION,在创建AuthScope时用作远程主机。这会创建一个Catch-22情况,其中NTLM无法使用HttpTransportProperties.Authenticator技术。您要么获得“401未授权”,要么获得“未找到&lt; REALM&gt; @HOST的凭据”。

请参阅https://issues.apache.org/jira/browse/AXIS2-4595

彼得

答案 1 :(得分:3)

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 :(得分:2)

根据此链接NTLM issues with Axis2

的说明
  

Axis2仍然使用旧的HTTPClient库,似乎该版本不支持NTLM的所有版本(v1,v2)。而且,将传输切换到HTTPClient v4.1

并非易事

我放弃了Axis2并改为使用CXF

以下链接确实让我们超越了Kerboros / NTLM问题

http://download.oracle.com/javase/6/docs/technotes/guides/net/http-auth.html

答案 3 :(得分:0)

JCIFS的替代方法是在自定义Apache Commons HTTP AuthScheme中使用Apache HTTPComponents 4 NTLMScheme(works with new NTLM):

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 vc.bjn.catalyst.forecast.BackportedNTLMScheme.getID()");
    }


    @Override
    @Deprecated
    public String authenticate(final Credentials credentials, final String method, final String uri) throws AuthenticationException {
        throw new RuntimeException("deprecated vc.bjn.catalyst.forecast.BackportedNTLMScheme.authenticate(Credentials, String, String)");
    }
}

用法

AuthPolicy.registerAuthScheme(AuthPolicy.NTLM, BackportedNTLMScheme.class);

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