【问题标题】:How to use NTLM authentication with Apache Wink client如何在 Apache Wink 客户端中使用 NTLM 身份验证
【发布时间】:2014-03-19 09:59:11
【问题描述】:

我正在尝试使用 wink-client v1.4 与 Sharepoint RESTful Web 服务进行通信。我创建了一个简单的 Java SE Maven 项目,它可以使用 BasicAuthSecurityHandler 在 Windows 上执行此任务。但是,同一项目在 Mac OS X 上不起作用。我在 Mac 上收到 401 HTTP 状态代码。 Wink 在从 Windows 运行时以某种方式使用我的 NTLM 凭据。我在两个平台上都使用 JDK 7。

如何在 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();
}

【问题讨论】:

  • 我收到了一个 GET 请求,要求在 OS X 上使用 Apache HttpClient v4.0.1 进行 NTLM 身份验证。我点击了这个链接:zhangyelei.blogspot.com/2014/03/…。这是至关重要的第一步,因为 HttpClient 版本用于 WAS v8.0 和 v8.5。要覆盖该版本,您必须采取荒谬的措施,例如隔离共享库。这对某些人来说可能是不可行的,就像我的情况一样。现在,我只需要弄清楚如何将 Apache HttpClient v4.0.1 与 Apache Wink 一起使用。

标签: java sharepoint ntlm apache-wink


【解决方案1】:

我想通了。

我的最终目标是创建一个可以移植到 WebSphere Application Server v8.0 的简单测试用例。 Apache Wink 客户端无法自行处理 NTLM 身份验证。您必须使用单独的 Http 客户端来处理 NTLM 身份验证。我选择了 Apache Http Cient v4.0.1,因为那个有缺陷的版本被打包在 WAS v8.0 中。覆盖提供的版本也是一个巨大的痛苦。这就是为什么我没有选择更新更好的 Apache HttpClient 版本的原因。

所以,下面是如何让 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>

我正在使用 WAS v8.0 中包含的 com.ibm.ws.prereq.jaxrs.jar 来获取 Apache Http Client v4.0.1。它安装在我的 Maven 存储库中,我将其指定为获取 Http Client v4.0.1 的依赖项。

按照步骤here

现在,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();
}

现在,最后一点。我使用 MOXy 作为我的 JAXB 实现。即使我在我的 app 变量中注册它,我也遇到了一些问题。我看到了一些与杰克逊有关的错误。 Apache HttpClient v4.0.1 显然在后台使用 Jackons 作为默认值。这是我为克服这个问题所做的。

我添加了以下依赖项:

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

这是 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 {

}

我观察了从 Sharepoint 返回的 String 结果,然后创建了一堆 MOXy POJO 模仿 JSON 对象层次结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 2022-10-13
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多