如何使用 JAX-RS 2.0 兼容的 RESTEasy 客户端 API 启用 NTLM 身份验证?
How to enable NTLM authentication with JAX-RS 2.0 compliant RESTEasy client API?
默认情况下,使用 RESTEasy 客户端 API 向需要 NTLM 身份验证的安全资源发送请求会导致状态为 401 Unauthorized
和 header WWW-Authenticate: NTLM
的 HTTP 响应。
如何使用 RESTEasy 客户端启用 NTLM 身份验证 API 以及如何提供凭据?
已有相关问题提供了有用的答案:
- RESTEasy client framework authentication credentials
- Basic Authentication with Resteasy client
它们有些过时(使用已弃用的和遗留的 API)并且要求略有不同。
在使用 JAX-RS 2.0 兼容的 RESTEasy 客户端从 Java 中使用 ASP.NET Web API 托管在 Internet Information Services (IIS) 上的 REST 服务的任务中挣扎之后API,我想在回答这个问题时分享我的经验。
RESTEasy 客户端 API 的身份验证由封装的 ClientHttpEngine 完成。我在这个答案中提到的版本 3.0.19.Final 符合 JAX-RS 2.0 并附带两个实现。两者都可以进行 NTLM 身份验证。
使用默认值ApacheHttpClient4Engine
即使它是默认引擎,您也需要设置一个自定义实例来提供凭据。首先 Credentials have to be added to a CredentialsProvider with respect to an concrete AuthScope. The next step is to set them up on a 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 which somehow invokes an Authenticator to do authentication. To provide the credentials you must override 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 客户端 API 向需要 NTLM 身份验证的安全资源发送请求会导致状态为 401 Unauthorized
和 header WWW-Authenticate: NTLM
的 HTTP 响应。
如何使用 RESTEasy 客户端启用 NTLM 身份验证 API 以及如何提供凭据?
已有相关问题提供了有用的答案:
- RESTEasy client framework authentication credentials
- Basic Authentication with Resteasy client
它们有些过时(使用已弃用的和遗留的 API)并且要求略有不同。
在使用 JAX-RS 2.0 兼容的 RESTEasy 客户端从 Java 中使用 ASP.NET Web API 托管在 Internet Information Services (IIS) 上的 REST 服务的任务中挣扎之后API,我想在回答这个问题时分享我的经验。
RESTEasy 客户端 API 的身份验证由封装的 ClientHttpEngine 完成。我在这个答案中提到的版本 3.0.19.Final 符合 JAX-RS 2.0 并附带两个实现。两者都可以进行 NTLM 身份验证。
使用默认值ApacheHttpClient4Engine
即使它是默认引擎,您也需要设置一个自定义实例来提供凭据。首先 Credentials have to be added to a CredentialsProvider with respect to an concrete AuthScope. The next step is to set them up on a 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 which somehow invokes an Authenticator to do authentication. To provide the credentials you must override 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();