axis2客户端NTLM身份验证

发布于 2024-11-04 08:34:40 字数 1010 浏览 0 评论 0原文

我有一个 axis2 (v1.5.3) 客户端,需要使用 IIS 进行 Kerberos/NTLM 身份验证。我该怎么做?这是我现在拥有的代码,它失败并出现 401 - 未经授权 错误:

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;

I have an axis2 (v1.5.3) client that needs to do Kerberos/NTLM authentication with IIS. How can I do this? This is the code I have right now and it fails with 401 - unauthorized error:

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);  

A client written in C# works fine with the same auth settings:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

娜些时光,永不杰束 2024-11-11 08:34:40

AXIS2 中的 NTLM 存在问题。它以 ntlm.setHost() 方法为中心。此处的条目既用作 NTLM 交换中的工作站,也用作创建 AuthScope 时的远程主机。这会造成第 22 条军规 (Catch-22) 情况,其中 NTLM 无法使用 HttpTransportProperties.Authenticator 技术工作。您要么收到“401 未经授权”,要么收到“未找到@HOST 的凭据”。

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

彼得

There is a problem with NTLM in AXIS2. It centres around the ntlm.setHost() method. The entry here is used as both WORKSTATION in the NTLM exchange and as Remote Host when AuthScope is created. This creates a Catch-22 situation where NTLM does not work using the HttpTransportProperties.Authenticator technique. You either get a "401 unauthorized" or you get a "No credentials found for < REALM>@HOST".

See https://issues.apache.org/jira/browse/AXIS2-4595

Peter

活雷疯 2024-11-11 08:34:40

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

http://devsac.blogspot.com/2010/10/supoprt-for-ntlmv2-with-apache.html

我刚刚使用了 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); 

HttpClient doesnt support NTLM v2 hence I use JCIFS library to return NTLM v1,2,3 message type as described in this website

http://devsac.blogspot.com/2010/10/supoprt-for-ntlmv2-with-apache.html

I just used the JCIFS_NTLMScheme.java file from the above website to register the auth scheme and it worked !!!!

Sample client:

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); 
你丑哭了我 2024-11-11 08:34:40

根据此链接中的注释Axis2 的 NTLM 问题

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

Based on the notes at this link NTLM issues with Axis2

Axis2 still uses old HTTPClient library and it seems that version does not support all versions(v1, v2 ) of NTLM. And also it was not trivial to switch the transport to HTTPClient v4.1

I gave up on Axis2 and used CXF instead.

The following link really us get past the Kerboros/NTLM issues

http://download.oracle.com/javase/6/docs/technotes/guides/net/http-auth.html
不弃不离 2024-11-11 08:34:40

JCIFS 的替代方法是使用 Apache HTTPComponents 4 NTLMScheme(它与新的NTLM)位于自定义 Apache Commons HTTP AuthScheme 中:

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 上对此进行了测试。

An alternative to JCIFS is to use the Apache HTTPComponents 4 NTLMScheme (which works with new NTLM) inside a custom Apache Commons HTTP AuthScheme:

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)");
    }
}

Usage

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

I tested this on IIS 7.5 on Windows Server 2008 R2.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文