简体   繁体   English

如何在Apache Wink客户端上使用NTLM身份验证

[英]How to use NTLM authentication with Apache Wink client

I'm trying to use wink-client v1.4 to communicate with a Sharepoint RESTful web service. 我正在尝试使用wink-client v1.4与Sharepoint RESTful Web服务进行通信。 I have created a simple Java SE Maven project that can do this task on Windows using a BasicAuthSecurityHandler. 我创建了一个简单的Java SE Maven项目,可以使用BasicAuthSecurityHandler在Windows上执行此任务。 However, this same project doesn't work on Mac OS X. I receive a 401 HTTP status code on the Mac. 但是,该项目在Mac OS X上不起作用。我在Mac上收到401 HTTP状态代码。 Wink is somehow using my NTLM credentials when being run from Windows. 从Windows运行时,Wink以某种方式使用了我的NTLM凭据。 I'm using JDK 7 for both platforms. 我在两个平台上都使用JDK 7。

How can I use NTLM authentication with Apache Wink client? 如何在Apache Wink客户端上使用NTLM身份验证?

public String getSharepointInfo() {
    spUser = "user";
    spPassword = "password";
    spUri = "https://someSharepointURL/";

    ClientConfig clientConfig = new ClientConfig();

    Application app = new Application() {
        public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(WinkMOXyJsonProvider.class);
            return classes;
        }
    };
    clientConfig.applications(app);
    BasicAuthSecurityHandler basicAuthSecurityHandler = new BasicAuthSecurityHandler();
    basicAuthSecurityHandler.setUserName(spUser);
    basicAuthSecurityHandler.setPassword(spPassword);
    clientConfig.handlers(basicAuthSecurityHandler);
    RestClient client = new RestClient(clientConfig);
    Resource resource = client.resource(spUri);

    ClientResponse response = resource.accept("*/*").get();

    String blah = response.getEntity(String.class);
    System.out.println("The response is " + blah);
    return blah.toString();
}

I've figured it out. 我知道了。

My ultimate goal was to create a simple test case that I could port to WebSphere Application Server v8.0. 我的最终目标是创建一个可以移植到WebSphere Application Server v8.0的简单测试用例。 The Apache Wink client can't handle NTLM authentication on its own. Apache Wink客户端无法自行处理NTLM身份验证。 You have to use a separate Http client to handle NTLM authentication. 您必须使用单独的Http客户端来处理NTLM身份验证。 I chose Apache Http Cient v4.0.1, since that buggy version is packaged in WAS v8.0. 我选择了Apache Http Cient v4.0.1,因为该错误版本包装在WAS v8.0中。 It's a huge pain to override that provided version too. 覆盖提供的版本也很痛苦。 That's why I didn't choose a more recent, better version of Apache HttpClient. 这就是为什么我没有选择更新的,更好的Apache HttpClient版本的原因。

So, here's how you get Apache Http Client v4.0.1 to handle NTLM authentication: Use the following dependencies... 因此,这是获取Apache Http Client v4.0.1来处理NTLM身份验证的方法:使用以下依赖项...

    <dependency>
        <groupId>jcifs</groupId>
        <artifactId>jcifs</artifactId>
        <version>1.3.17</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.apache.wink</groupId>
        <artifactId>wink-client</artifactId>
        <version>1.4</version>
    </dependency>

I'm using com.ibm.ws.prereq.jaxrs.jar contained in WAS v8.0 to get Apache Http Client v4.0.1. 我正在使用WAS v8.0中包含的com.ibm.ws.prereq.jaxrs.jar来获取Apache Http Client v4.0.1。 That's installed in my Maven repo, and I specify that as a dependency to get Http Client v4.0.1. 那已经安装在我的Maven仓库中,我将其指定为获取Http Client v4.0.1的依赖项。

Follow the steps here . 请按照此处的步骤操作。

Now, Wink comes into play: 现在,Wink开始发挥作用:

public int attemptWinkHttpClienGET() {
    ClientResponse response = null;
    try {
        String spUri = "https://some-sharepoint-url/listdata.svc/";

        StringBuilder sb = new StringBuilder();
        sb.append(spUri).append("UserInformationList").toString();

        DefaultHttpClient httpClient = new DefaultHttpClient();
        httpClient.getAuthSchemes().register("ntlm",new JCIFSNTLMSchemeFactory());
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        NTCredentials ntcred = new NTCredentials("username_here", "password_here", InetAddress.getLocalHost().getHostName(), "domain_here");
        credsProvider.setCredentials(new AuthScope("base_url_here_sans_https://", 443, AuthScope.ANY_REALM, "NTLM"), ntcred);
        httpClient.setCredentialsProvider(credsProvider);

        org.apache.wink.client.ClientConfig httpClientConfig = new org.apache.wink.client.ApacheHttpClientConfig(httpClient);
        Application app = new Application() {
            public Set<Class<?>> getClasses() {
                Set<Class<?>> classes = new HashSet<Class<?>>();
                classes.add(WinkMOXyJsonProvider.class);
                return classes;
            }
        };
        httpClientConfig.applications(app);
        RestClient client = new RestClient(httpClientConfig);
        Resource resource = client.resource(sb.toString());
        response = resource.accept(MediaType.APPLICATION_JSON_TYPE).get();
        UserInformationListResponse blah = response.getEntity(UserInformationListResponse.class);
        Results[] results = blah.getD().getResults();
        for (Results result : results) {
            System.out.println("User Name: " + result.getFirstName() + " " + result.getLastName());
        }
        System.out.println("The response is " + response.getStatusCode());
        response.consumeContent();
    } catch (UnknownHostException ex) {
        Logger.getLogger(HttpTest.class.getName()).log(Level.SEVERE, null, ex);
    }

    return response.getStatusCode();
}

Now, the final bit. 现在,最后一点。 I use MOXy as my JAXB implementation. 我使用MOXy作为我的JAXB实现。 I had some issues getting it to work even though I was registering it in my app variable. 即使我在我的应用变量中注册它,我也遇到了一些问题,使其无法正常工作。 I was seeing some Jackson-related errors. 我看到了一些与杰克逊有关的错误。 Apache HttpClient v4.0.1 is apparently using Jackons under the hood as a default. Apache HttpClient v4.0.1显然是在默认情况下使用Jackons。 Here's what I did to overcome that problem. 这是我为克服该问题所做的工作。

I added the following dependencies: 我添加了以下依赖项:

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-moxy</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.4.0-rc2</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-xc</artifactId>
        <version>1.9.13</version>
    </dependency>

Here's WinkMOXyJsonProvider.java 这是WinkMOXyJsonProvider.java

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;

@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class WinkMOXyJsonProvider extends MOXyJsonProvider {

}

I observed the String result returned from Sharepoint and then created a bunch of MOXy POJO's mimicking the JSON object hierarchy. 我观察到从Sharepoint返回的String结果,然后创建了一堆模仿JSON对象层次结构的MOXy POJO。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM