如何使用符合 JAX-RS 2.0 的 RESTEasy 客户端 API 启用 NTLM 身份验证?

Posted

技术标签:

【中文标题】如何使用符合 JAX-RS 2.0 的 RESTEasy 客户端 API 启用 NTLM 身份验证?【英文标题】:How to enable NTLM authentication with JAX-RS 2.0 compliant RESTEasy client API? 【发布时间】:2019-06-08 15:29:00 【问题描述】:

默认情况下,使用 RESTEasy 客户端 API 将请求发送到需要 NTLM 身份验证的安全资源会导致 HTTP 响应状态为 401 Unauthorized,标头为 WWW-Authenticate: NTLM

如何使用 RESTEasy 客户端 API 启用 NTLM 身份验证以及如何提供凭据?

已经有相关的问题和有用的答案:

RESTEasy client framework authentication credentials Java RESTful client [RESTEasy or Apache HttpClient] - NTLM on the other side Basic Authentication with Resteasy client

它们有些过时(使用已弃用和遗留的 API)并且要求略有不同。

在努力完成使用 JAX-RS 2.0 兼容的 RESTEasy 客户端 API 从 Java 使用托管在 Internet 信息服务 (IIS) 上的 ASP.NET Web API REST 服务的任务之后,我想分享我的经验总结回答这个问题。

【问题讨论】:

【参考方案1】:

RESTEasy Client API 的身份验证由封装的ClientHttpEngine 完成。我在这个答案中提到的版本 3.0.19.Final 符合 JAX-RS 2.0 并附带两个实现。两者都可以进行 NTLM 身份验证。

使用默认的ApacheHttpClient4Engine

即使它是默认引擎,您也需要设置一个自定义实例来提供凭据。首先,Credentials 必须相对于具体的AuthScope 添加到CredentialsProvider。下一步是在 HttpClientContext 上设置它们,然后需要再次将其提供给引擎。

Credentials credentials = new NTCredentials("user", "password", "workstation", "domain");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
  new AuthScope(null, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.NTLM)
  , credentials
);
HttpClientContext httpContext = HttpClientContext.create();
httpContext.setCredentialsProvider(credentialsProvider);
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) 
  ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient, httpContext);
  ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
  // work with the client

使用URLConnectionEngine

该引擎使用HttpURLConnection,它以某种方式调用Authenticator 进行身份验证。要提供凭据,您必须在自定义子类中覆盖 getPasswordAuthentication 并将其注册为默认值。

public class NTLMAuthenticator extends Authenticator 
  @Override
  protected PasswordAuthentication getPasswordAuthentication() 
    return new PasswordAuthentication("domain\\user", "password".toCharArray());
  

Authenticator.setDefault(new NTLMAuthenticator());
ResteasyClient client =
  new ResteasyClientBuilder().httpEngine(new URLConnectionEngine()).build();
// work with the client
client.close();

资源

RESTEasy JAX-RS 3.0.19.Final Documentation HttpClient Tutorial Http Authentication

【讨论】:

以上是关于如何使用符合 JAX-RS 2.0 的 RESTEasy 客户端 API 启用 NTLM 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

在 JAX-RS 2.0 客户端库中处理自定义错误响应

JAX-RS(REST Web Services)2.0 can not be installed: One or more constraints have not been satisfied

Eclipse JAX-RS (REST Web Services) 2.0 requires Java 1.6 or newer

RESTEasy中的通用异常处理ExceptionMapper

如何使用 JAX-RS 和 Jersey 处理 CORS

如何使用 CXF 为 JAX-RS 客户端设置超时