2009-07-08 19:07:17 +00:00
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
|
|
<!--
|
|
|
|
====================================================================
|
|
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
|
|
or more contributor license agreements. See the NOTICE file
|
|
|
|
distributed with this work for additional information
|
|
|
|
regarding copyright ownership. The ASF licenses this file
|
|
|
|
to you under the Apache License, Version 2.0 (the
|
|
|
|
"License"); you may not use this file except in compliance
|
|
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
|
|
software distributed under the License is distributed on an
|
|
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
KIND, either express or implied. See the License for the
|
|
|
|
specific language governing permissions and limitations
|
|
|
|
under the License.
|
|
|
|
====================================================================
|
|
|
|
-->
|
2009-07-09 19:30:05 +00:00
|
|
|
<chapter id="authentication">
|
2009-07-08 19:07:17 +00:00
|
|
|
<title>HTTP authentication</title>
|
|
|
|
<para>HttpClient provides full support for authentication schemes defined by the HTTP standard
|
2010-11-03 16:09:07 +00:00
|
|
|
specification as well as a number of widely used non-standard authentication schemes such
|
|
|
|
as <literal>NTLM</literal> and <literal>SPNEGO</literal>.</para>
|
2009-07-08 19:07:17 +00:00
|
|
|
<section>
|
|
|
|
<title>User credentials</title>
|
|
|
|
<para>Any process of user authentication requires a set of credentials that can be used to
|
2010-12-02 01:08:08 +00:00
|
|
|
establish user identity. In the simplest form user credentials can be just a user name /
|
2009-07-08 19:07:17 +00:00
|
|
|
password pair. <classname>UsernamePasswordCredentials</classname> represents a set of
|
|
|
|
credentials consisting of a security principal and a password in clear text. This
|
|
|
|
implementation is sufficient for standard authentication schemes defined by the HTTP
|
|
|
|
standard specification.</para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd");
|
|
|
|
System.out.println(creds.getUserPrincipal().getName());
|
|
|
|
System.out.println(creds.getPassword());
|
|
|
|
]]></programlisting>
|
|
|
|
<para>stdout ></para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
user
|
|
|
|
pwd
|
|
|
|
]]></programlisting>
|
|
|
|
<para><classname>NTCredentials</classname> is a Microsoft Windows specific implementation
|
|
|
|
that includes in addition to the user name / password pair a set of additional Windows
|
2010-12-02 01:08:08 +00:00
|
|
|
specific attributes such as the name of the user domain. In a Microsoft Windows network
|
|
|
|
the same user can belong to multiple domains each with a different set of
|
2009-07-08 19:07:17 +00:00
|
|
|
authorizations.</para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
NTCredentials creds = new NTCredentials("user", "pwd", "workstation", "domain");
|
|
|
|
System.out.println(creds.getUserPrincipal().getName());
|
|
|
|
System.out.println(creds.getPassword());
|
|
|
|
]]></programlisting>
|
|
|
|
<para>stdout ></para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
DOMAIN/user
|
|
|
|
pwd
|
|
|
|
]]></programlisting>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
|
|
<title>Authentication schemes</title>
|
|
|
|
<para>The <interfacename>AuthScheme</interfacename> interface represents an abstract
|
|
|
|
challenge-response oriented authentication scheme. An authentication scheme is expected
|
|
|
|
to support the following functions:</para>
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>Parse and process the challenge sent by the target server in response to
|
|
|
|
request for a protected resource.</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>Provide properties of the processed challenge: the authentication scheme type
|
|
|
|
and its parameters, such the realm this authentication scheme is applicable to,
|
|
|
|
if available</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>Generate the authorization string for the given set of credentials and the HTTP
|
2009-07-08 19:07:17 +00:00
|
|
|
request in response to the actual authorization challenge.</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>Please note that authentication schemes may be stateful involving a series of
|
2009-07-08 19:07:17 +00:00
|
|
|
challenge-response exchanges.</para>
|
|
|
|
<para>HttpClient ships with several <interfacename>AuthScheme</interfacename>
|
|
|
|
implementations:</para>
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<formalpara>
|
|
|
|
<title>Basic:</title>
|
|
|
|
<para>Basic authentication scheme as defined in RFC 2617. This authentication
|
|
|
|
scheme is insecure, as the credentials are transmitted in clear text.
|
|
|
|
Despite its insecurity Basic authentication scheme is perfectly adequate if
|
|
|
|
used in combination with the TLS/SSL encryption.</para>
|
|
|
|
</formalpara>
|
2009-09-16 12:17:13 +00:00
|
|
|
</listitem>
|
|
|
|
<listitem>
|
2009-07-08 19:07:17 +00:00
|
|
|
<formalpara>
|
|
|
|
<title>Digest</title>
|
|
|
|
<para>Digest authentication scheme as defined in RFC 2617. Digest authentication
|
|
|
|
scheme is significantly more secure than Basic and can be a good choice for
|
|
|
|
those applications that do not want the overhead of full transport security
|
|
|
|
through TLS/SSL encryption.</para>
|
|
|
|
</formalpara>
|
2009-09-16 12:17:13 +00:00
|
|
|
</listitem>
|
2009-09-24 19:35:03 +00:00
|
|
|
<listitem>
|
2009-07-08 19:07:17 +00:00
|
|
|
<formalpara>
|
|
|
|
<title>NTLM:</title>
|
|
|
|
<para>NTLM is a proprietary authentication scheme developed by Microsoft and
|
|
|
|
optimized for Windows platforms. NTLM is believed to be more secure than
|
2010-11-03 16:09:07 +00:00
|
|
|
Digest.</para>
|
2009-07-08 19:07:17 +00:00
|
|
|
</formalpara>
|
|
|
|
</listitem>
|
2009-09-26 11:57:23 +00:00
|
|
|
<listitem>
|
|
|
|
<formalpara>
|
2012-02-04 16:30:30 +00:00
|
|
|
<title>SPNEGO:</title>
|
2009-09-26 11:57:23 +00:00
|
|
|
<para><literal>SPNEGO</literal> (<emphasis>S</emphasis>imple and
|
|
|
|
<emphasis>P</emphasis>rotected <literal>GSSAPI</literal>
|
|
|
|
<emphasis>Nego</emphasis>tiation Mechanism) is a <literal>GSSAPI</literal>
|
|
|
|
"pseudo mechanism" that is used to negotiate one of a number of possible
|
|
|
|
real mechanisms. SPNEGO's most visible use is in Microsoft's <literal>HTTP
|
|
|
|
Negotiate</literal> authentication extension. The negotiable
|
|
|
|
sub-mechanisms include NTLM and Kerberos supported by Active Directory.
|
2010-12-02 01:08:08 +00:00
|
|
|
At present HttpClient only supports the Kerberos sub-mechanism. </para>
|
2009-09-26 11:57:23 +00:00
|
|
|
</formalpara>
|
|
|
|
</listitem>
|
2012-02-04 16:30:30 +00:00
|
|
|
<listitem>
|
|
|
|
<formalpara>
|
|
|
|
<title>Kerberos:</title>
|
|
|
|
<para>Kerberos authentication implementation. </para>
|
|
|
|
</formalpara>
|
|
|
|
</listitem>
|
2009-07-08 19:07:17 +00:00
|
|
|
</itemizedlist>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
|
|
<title>Credentials provider</title>
|
|
|
|
<para>Credentials providers are intended to maintain a set of user credentials and to be
|
|
|
|
able to produce user credentials for a particular authentication scope. Authentication
|
|
|
|
scope consists of a host name, a port number, a realm name and an authentication scheme
|
|
|
|
name. When registering credentials with the credentials provider one can provide a wild
|
|
|
|
card (any host, any port, any realm, any scheme) instead of a concrete attribute value.
|
|
|
|
The credentials provider is then expected to be able to find the closest match for a
|
|
|
|
particular scope if the direct match cannot be found.</para>
|
|
|
|
<para>HttpClient can work with any physical representation of a credentials provider that
|
|
|
|
implements the <interfacename>CredentialsProvider</interfacename> interface. The default
|
|
|
|
<interfacename>CredentialsProvider</interfacename> implementation called
|
|
|
|
<classname>BasicCredentialsProvider</classname> is a simple implementation backed by
|
|
|
|
a <classname>java.util.HashMap</classname>.</para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
|
|
|
credsProvider.setCredentials(
|
|
|
|
new AuthScope("somehost", AuthScope.ANY_PORT),
|
|
|
|
new UsernamePasswordCredentials("u1", "p1"));
|
|
|
|
credsProvider.setCredentials(
|
|
|
|
new AuthScope("somehost", 8080),
|
|
|
|
new UsernamePasswordCredentials("u2", "p2"));
|
|
|
|
credsProvider.setCredentials(
|
|
|
|
new AuthScope("otherhost", 8080, AuthScope.ANY_REALM, "ntlm"),
|
|
|
|
new UsernamePasswordCredentials("u3", "p3"));
|
|
|
|
|
|
|
|
System.out.println(credsProvider.getCredentials(
|
|
|
|
new AuthScope("somehost", 80, "realm", "basic")));
|
|
|
|
System.out.println(credsProvider.getCredentials(
|
|
|
|
new AuthScope("somehost", 8080, "realm", "basic")));
|
|
|
|
System.out.println(credsProvider.getCredentials(
|
|
|
|
new AuthScope("otherhost", 8080, "realm", "basic")));
|
|
|
|
System.out.println(credsProvider.getCredentials(
|
|
|
|
new AuthScope("otherhost", 8080, null, "ntlm")));
|
|
|
|
]]></programlisting>
|
|
|
|
<para>stdout ></para>
|
|
|
|
<programlisting><![CDATA[
|
|
|
|
[principal: u1]
|
|
|
|
[principal: u2]
|
|
|
|
null
|
|
|
|
[principal: u3]
|
|
|
|
]]></programlisting>
|
|
|
|
</section>
|
|
|
|
<section>
|
|
|
|
<title>HTTP authentication and execution context</title>
|
|
|
|
<para>HttpClient relies on the <classname>AuthState</classname> class to keep track of
|
|
|
|
detailed information about the state of the authentication process. HttpClient creates
|
|
|
|
two instances of <classname>AuthState</classname> in the course of HTTP request
|
|
|
|
execution: one for target host authentication and another one for proxy authentication.
|
|
|
|
In case the target server or the proxy require user authentication the respective
|
|
|
|
<classname>AuthScope</classname> instance will be populated with the
|
|
|
|
<classname>AuthScope</classname>, <interfacename>AuthScheme</interfacename> and
|
|
|
|
<interfacename>Crednetials</interfacename> used during the authentication process.
|
|
|
|
The <classname>AuthState</classname> can be examined in order to find out what kind of
|
|
|
|
authentication was requested, whether a matching
|
|
|
|
<interfacename>AuthScheme</interfacename> implementation was found and whether the
|
|
|
|
credentials provider managed to find user credentials for the given authentication
|
|
|
|
scope.</para>
|
|
|
|
<para>In the course of HTTP request execution HttpClient adds the following authentication
|
|
|
|
related objects to the execution context:</para>
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<formalpara>
|
2013-08-14 18:41:58 +00:00
|
|
|
<para><interfacename>Lookup</interfacename> instance representing the actual
|
2009-07-08 19:07:17 +00:00
|
|
|
authentication scheme registry. The value of this attribute set in the local
|
|
|
|
context takes precedence over the default one.</para>
|
|
|
|
</formalpara>
|
2009-09-16 12:17:13 +00:00
|
|
|
</listitem>
|
|
|
|
<listitem>
|
2009-07-08 19:07:17 +00:00
|
|
|
<formalpara>
|
2013-08-14 18:41:58 +00:00
|
|
|
<para><interfacename>CredentialsProvider</interfacename> instance representing
|
|
|
|
the actual credentials provider. The value of this attribute set in the
|
|
|
|
local context takes precedence over the default one.</para>
|
2009-07-08 19:07:17 +00:00
|
|
|
</formalpara>
|
2009-09-16 12:17:13 +00:00
|
|
|
</listitem>
|
|
|
|
<listitem>
|
2009-07-08 19:07:17 +00:00
|
|
|
<formalpara>
|
|
|
|
<para><classname>AuthState</classname> instance representing the actual target
|
|
|
|
authentication state. The value of this attribute set in the local context
|
|
|
|
takes precedence over the default one.</para>
|
|
|
|
</formalpara>
|
2009-09-16 12:17:13 +00:00
|
|
|
</listitem>
|
|
|
|
<listitem>
|
2009-07-08 19:07:17 +00:00
|
|
|
<formalpara>
|
|
|
|
<para><classname>AuthState</classname> instance representing the actual proxy
|
|
|
|
authentication state. The value of this attribute set in the local context
|
|
|
|
takes precedence over the default one.</para>
|
|
|
|
</formalpara>
|
|
|
|
</listitem>
|
2009-11-18 21:07:35 +00:00
|
|
|
<listitem>
|
|
|
|
<formalpara>
|
|
|
|
<para><interfacename>AuthCache</interfacename> instance representing the actual
|
|
|
|
authentication data cache. The value of this attribute set in the local
|
|
|
|
context takes precedence over the default one.</para>
|
|
|
|
</formalpara>
|
|
|
|
</listitem>
|
2009-07-08 19:07:17 +00:00
|
|
|
</itemizedlist>
|
|
|
|
<para>The local <interfacename>HttpContext</interfacename> object can be used to customize
|
2010-12-02 01:08:08 +00:00
|
|
|
the HTTP authentication context prior to request execution, or to examine its state after
|
2009-07-08 19:07:17 +00:00
|
|
|
the request has been executed:</para>
|
|
|
|
<programlisting><![CDATA[
|
2013-08-14 18:41:58 +00:00
|
|
|
CloseableHttpClient httpclient = <...>
|
|
|
|
|
|
|
|
CredentialsProvider credsProvider = <...>
|
|
|
|
Lookup<AuthSchemeProvider> authRegistry = <...>
|
|
|
|
AuthCache authCache = <...>
|
|
|
|
|
|
|
|
HttpClientContext context = HttpClientContext.create();
|
|
|
|
context.setCredentialsProvider(credsProvider);
|
|
|
|
context.setAuthSchemeRegistry(authRegistry);
|
|
|
|
context.setAuthCache(authCache);
|
|
|
|
HttpGet httpget = new HttpGet("http://somehost/");
|
|
|
|
CloseableHttpResponse response1 = httpclient.execute(httpget, context);
|
|
|
|
<...>
|
2009-07-08 19:07:17 +00:00
|
|
|
|
2013-08-14 18:41:58 +00:00
|
|
|
AuthState proxyAuthState = context.getProxyAuthState();
|
2012-02-04 16:30:30 +00:00
|
|
|
System.out.println("Proxy auth state: " + proxyAuthState.getState());
|
2009-07-08 19:07:17 +00:00
|
|
|
System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
|
|
|
|
System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
|
2013-08-14 18:41:58 +00:00
|
|
|
AuthState targetAuthState = context.getTargetAuthState();
|
2012-02-04 16:30:30 +00:00
|
|
|
System.out.println("Target auth state: " + targetAuthState.getState());
|
2009-07-08 19:07:17 +00:00
|
|
|
System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
|
|
|
|
System.out.println("Target auth credentials: " + targetAuthState.getCredentials());
|
|
|
|
]]></programlisting>
|
|
|
|
</section>
|
2009-11-18 21:07:35 +00:00
|
|
|
<section>
|
|
|
|
<title>Caching of authentication data</title>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>As of version 4.1 HttpClient automatically caches information about hosts it has
|
2009-11-18 21:07:35 +00:00
|
|
|
successfully authenticated with. Please note that one must use the same execution
|
|
|
|
context to execute logically related requests in order for cached authentication data
|
|
|
|
to propagate from one request to another. Authentication data will be lost as soon as
|
|
|
|
the execution context goes out of scope.</para>
|
|
|
|
</section>
|
2009-07-08 19:07:17 +00:00
|
|
|
<section>
|
|
|
|
<title>Preemptive authentication</title>
|
|
|
|
<para>HttpClient does not support preemptive authentication out of the box, because if
|
|
|
|
misused or used incorrectly the preemptive authentication can lead to significant
|
|
|
|
security issues, such as sending user credentials in clear text to an unauthorized third
|
|
|
|
party. Therefore, users are expected to evaluate potential benefits of preemptive
|
|
|
|
authentication versus security risks in the context of their specific application
|
2009-11-18 21:07:35 +00:00
|
|
|
environment.</para>
|
2013-10-18 09:30:35 +00:00
|
|
|
<para>Nonetheless one can configure HttpClient to authenticate preemptively by prepopulating
|
2009-11-18 21:07:35 +00:00
|
|
|
the authentication data cache.</para>
|
2009-07-08 19:07:17 +00:00
|
|
|
<programlisting><![CDATA[
|
2013-08-14 18:41:58 +00:00
|
|
|
CloseableHttpClient httpclient = <...>
|
2009-07-08 19:07:17 +00:00
|
|
|
|
2013-08-14 18:41:58 +00:00
|
|
|
HttpHost targetHost = new HttpHost("localhost", 80, "http");
|
|
|
|
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
|
|
|
credsProvider.setCredentials(
|
|
|
|
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
|
2009-11-18 21:07:35 +00:00
|
|
|
new UsernamePasswordCredentials("username", "password"));
|
|
|
|
|
|
|
|
// Create AuthCache instance
|
|
|
|
AuthCache authCache = new BasicAuthCache();
|
|
|
|
// Generate BASIC scheme object and add it to the local auth cache
|
|
|
|
BasicScheme basicAuth = new BasicScheme();
|
|
|
|
authCache.put(targetHost, basicAuth);
|
|
|
|
|
|
|
|
// Add AuthCache to the execution context
|
2013-08-14 18:41:58 +00:00
|
|
|
HttpClientContext context = HttpClientContext.create();
|
|
|
|
context.setCredentialsProvider(credsProvider);
|
2013-10-28 10:50:55 +00:00
|
|
|
context.setAuthCache(authCache);
|
2009-11-18 21:07:35 +00:00
|
|
|
|
|
|
|
HttpGet httpget = new HttpGet("/");
|
|
|
|
for (int i = 0; i < 3; i++) {
|
2013-08-14 18:41:58 +00:00
|
|
|
CloseableHttpResponse response = httpclient.execute(
|
|
|
|
targetHost, httpget, context);
|
|
|
|
try {
|
|
|
|
HttpEntity entity = response.getEntity();
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
response.close();
|
|
|
|
}
|
2009-11-18 21:07:35 +00:00
|
|
|
}
|
2009-07-08 19:07:17 +00:00
|
|
|
]]></programlisting>
|
|
|
|
</section>
|
2009-09-13 13:21:13 +00:00
|
|
|
|
2009-10-28 20:38:54 +00:00
|
|
|
<section id="ntlm">
|
|
|
|
<title>NTLM Authentication</title>
|
2010-11-03 16:09:07 +00:00
|
|
|
<para>As of version 4.1 HttpClient provides full support for NTLMv1, NTLMv2, and NTLM2
|
|
|
|
Session authentication out of the box. One can still continue using an external
|
2009-10-28 20:38:54 +00:00
|
|
|
<literal>NTLM</literal> engine such as <ulink url="http://jcifs.samba.org/">JCIFS
|
|
|
|
</ulink> library developed by the <ulink url="http://www.samba.org/">Samba</ulink>
|
2010-11-03 16:09:07 +00:00
|
|
|
project as a part of their Windows interoperability suite of programs.
|
2009-10-28 20:38:54 +00:00
|
|
|
</para>
|
|
|
|
<section>
|
|
|
|
<title>NTLM connection persistence</title>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>The <literal>NTLM</literal> authentication scheme is significantly more expensive
|
2009-10-28 20:38:54 +00:00
|
|
|
in terms of computational overhead and performance impact than the standard
|
|
|
|
<literal>Basic</literal> and <literal>Digest</literal> schemes. This is likely to be
|
|
|
|
one of the main reasons why Microsoft chose to make <literal>NTLM</literal>
|
|
|
|
authentication scheme stateful. That is, once authenticated, the user identity is
|
|
|
|
associated with that connection for its entire life span. The stateful nature of
|
|
|
|
<literal>NTLM</literal> connections makes connection persistence more complex, as
|
|
|
|
for the obvious reason persistent <literal>NTLM</literal> connections may not be
|
|
|
|
re-used by users with a different user identity. The standard connection managers
|
|
|
|
shipped with HttpClient are fully capable of managing stateful connections. However,
|
|
|
|
it is critically important that logically related requests within the same session
|
|
|
|
use the same execution context in order to make them aware of the current user
|
|
|
|
identity. Otherwise, HttpClient will end up creating a new HTTP connection for each
|
|
|
|
HTTP request against <literal>NTLM</literal> protected resources. For detailed
|
|
|
|
discussion on stateful HTTP connections please refer to
|
|
|
|
<link linkend="stateful_conn">this </link> section. </para>
|
2010-12-08 16:18:20 +00:00
|
|
|
<!-- Note: the stateful_conn anchor is in the file advanced.xml -->
|
2009-10-28 20:38:54 +00:00
|
|
|
<para>As <literal>NTLM</literal> connections are stateful it is generally recommended
|
|
|
|
to trigger <literal>NTLM</literal> authentication using a relatively cheap method,
|
|
|
|
such as <literal>GET</literal> or <literal>HEAD</literal>, and re-use the same
|
|
|
|
connection to execute more expensive methods, especially those enclose a request
|
|
|
|
entity, such as <literal>POST</literal> or <literal>PUT</literal>. </para>
|
|
|
|
<programlisting><![CDATA[
|
2013-08-14 18:41:58 +00:00
|
|
|
CloseableHttpClient httpclient = <...>
|
2009-10-28 20:38:54 +00:00
|
|
|
|
2013-08-14 18:41:58 +00:00
|
|
|
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
|
|
|
credsProvider.setCredentials(AuthScope.ANY,
|
|
|
|
new NTCredentials("user", "pwd", "myworkstation", "microsoft.com"));
|
2009-10-28 20:38:54 +00:00
|
|
|
|
|
|
|
HttpHost target = new HttpHost("www.microsoft.com", 80, "http");
|
|
|
|
|
|
|
|
// Make sure the same context is used to execute logically related requests
|
2013-08-14 18:41:58 +00:00
|
|
|
HttpClientContext context = HttpClientContext.create();
|
|
|
|
context.setCredentialsProvider(credsProvider);
|
2009-10-28 20:38:54 +00:00
|
|
|
|
|
|
|
// Execute a cheap method first. This will trigger NTLM authentication
|
|
|
|
HttpGet httpget = new HttpGet("/ntlm-protected/info");
|
2013-08-14 18:41:58 +00:00
|
|
|
CloseableHttpResponse response1 = httpclient.execute(target, httpget, context);
|
|
|
|
try {
|
|
|
|
HttpEntity entity1 = response1.getEntity();
|
|
|
|
} finally {
|
|
|
|
response1.close();
|
|
|
|
}
|
2009-10-28 20:38:54 +00:00
|
|
|
|
|
|
|
// Execute an expensive method next reusing the same context (and connection)
|
|
|
|
HttpPost httppost = new HttpPost("/ntlm-protected/form");
|
|
|
|
httppost.setEntity(new StringEntity("lots and lots of data"));
|
2013-08-14 18:41:58 +00:00
|
|
|
CloseableHttpResponse response2 = httpclient.execute(target, httppost, context);
|
|
|
|
try {
|
|
|
|
HttpEntity entity2 = response2.getEntity();
|
|
|
|
} finally {
|
|
|
|
response2.close();
|
|
|
|
}
|
2009-10-28 20:38:54 +00:00
|
|
|
]]></programlisting>
|
|
|
|
</section>
|
|
|
|
</section>
|
|
|
|
|
2009-09-26 11:57:23 +00:00
|
|
|
<section id="spnego">
|
2009-09-13 13:21:13 +00:00
|
|
|
<title><literal>SPNEGO</literal>/Kerberos Authentication</title>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>The <literal>SPNEGO</literal> (<emphasis>S</emphasis>imple and
|
2009-09-24 19:35:03 +00:00
|
|
|
<emphasis>P</emphasis>rotected <literal>GSSAPI</literal>
|
|
|
|
<emphasis>Nego</emphasis>tiation Mechanism) is designed to allow for authentication to
|
|
|
|
services when neither end knows what the other can use/provide. It is most commonly used
|
|
|
|
to do Kerberos authentication. It can wrap other mechanisms, however the current version
|
2009-09-26 11:57:23 +00:00
|
|
|
in HttpClient is designed solely with Kerberos in mind. </para>
|
2009-09-24 19:35:03 +00:00
|
|
|
<sidebar>
|
2009-09-26 11:57:23 +00:00
|
|
|
<orderedlist numeration="arabic">
|
|
|
|
<listitem>
|
|
|
|
<para>Client Web Browser does HTTP GET for resource.</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>Web server returns HTTP 401 status and a header:
|
|
|
|
<literal>WWW-Authenticate: Negotiate</literal></para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>Client generates a <literal>NegTokenInit</literal>, base64 encodes it, and
|
|
|
|
resubmits the <literal>GET</literal> with an Authorization header:
|
|
|
|
<literal>Authorization: Negotiate <base64
|
|
|
|
encoding></literal>.</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>Server decodes the <literal>NegTokenInit</literal>, extracts the supported
|
|
|
|
<literal>MechTypes</literal> (only Kerberos V5 in our case), ensures it
|
|
|
|
is one of the expected ones, and then extracts the
|
|
|
|
<literal>MechToken</literal> (Kerberos Token) and authenticates
|
|
|
|
it.</para>
|
|
|
|
<para>If more processing is required another HTTP 401 is returned to the client
|
|
|
|
with more data in the the <literal>WWW-Authenticate</literal> header. Client
|
|
|
|
takes the info and generates another token passing this back in the
|
|
|
|
<literal>Authorization</literal> header until complete.</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>When the client has been authenticated the Web server should return the
|
|
|
|
HTTP 200 status, a final <literal>WWW-Authenticate</literal> header and the
|
|
|
|
page content.</para>
|
|
|
|
</listitem>
|
|
|
|
</orderedlist>
|
2009-09-13 13:21:13 +00:00
|
|
|
</sidebar>
|
|
|
|
<section>
|
2009-09-26 11:57:23 +00:00
|
|
|
<title><literal>SPNEGO</literal> support in HttpClient</title>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>The <literal>SPNEGO</literal> authentication scheme is compatible with Sun Java
|
2009-10-12 16:26:38 +00:00
|
|
|
versions 1.5 and up. However the use of Java >= 1.6 is strongly recommended as it
|
|
|
|
supports <literal>SPNEGO</literal> authentication more completely.</para>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>The Sun JRE provides the supporting classes to do nearly all the Kerberos and
|
2009-09-26 11:57:23 +00:00
|
|
|
<literal>SPNEGO</literal> token handling. This means that a lot of the setup is
|
2012-02-04 16:30:30 +00:00
|
|
|
for the GSS classes. The <classname>SPNegoScheme</classname> is a simple class to
|
2009-09-26 11:57:23 +00:00
|
|
|
handle marshalling the tokens and reading and writing the correct headers.</para>
|
|
|
|
<para>The best way to start is to grab the <literal>KerberosHttpClient.java</literal>
|
|
|
|
file in examples and try and get it to work. There are a lot of issues that can
|
2010-12-02 01:08:08 +00:00
|
|
|
happen but if lucky it'll work without too much of a problem. It should also provide some
|
2009-09-26 11:57:23 +00:00
|
|
|
output to debug with.</para>
|
2009-09-13 13:21:13 +00:00
|
|
|
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>In Windows it should default to using the logged in credentials; this can be
|
2009-09-24 19:35:03 +00:00
|
|
|
overridden by using 'kinit' e.g. <literal>$JAVA_HOME\bin\kinit
|
|
|
|
testuser@AD.EXAMPLE.NET</literal>, which is very helpful for testing and
|
2010-12-02 01:08:08 +00:00
|
|
|
debugging issues. Remove the cache file created by kinit to revert back to the windows
|
2009-09-24 19:35:03 +00:00
|
|
|
Kerberos cache.</para>
|
2009-09-26 11:57:23 +00:00
|
|
|
<para>Make sure to list <literal>domain_realms</literal> in the
|
|
|
|
<literal>krb5.conf</literal> file. This is a major source of problems.</para>
|
2009-09-13 13:21:13 +00:00
|
|
|
</section>
|
|
|
|
<section>
|
2009-09-26 11:57:23 +00:00
|
|
|
<title>GSS/Java Kerberos Setup</title>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>This documentation assumes you are using Windows but much of the information
|
2009-09-26 11:57:23 +00:00
|
|
|
applies to Unix as well.</para>
|
|
|
|
<para>The <classname>org.ietf.jgss</classname> classes have lots of possible
|
|
|
|
configuration parameters, mainly in the
|
|
|
|
<literal>krb5.conf</literal>/<literal>krb5.ini</literal> file. Some more info on
|
|
|
|
the format at <ulink
|
2009-09-24 19:35:03 +00:00
|
|
|
url="http://web.mit.edu/kerberos/krb5-1.4/krb5-1.4.1/doc/krb5-admin/krb5.conf.html"
|
|
|
|
>http://web.mit.edu/kerberos/krb5-1.4/krb5-1.4.1/doc/krb5-admin/krb5.conf.html</ulink>.</para>
|
2009-09-13 13:21:13 +00:00
|
|
|
</section>
|
|
|
|
<section>
|
2009-09-26 11:57:23 +00:00
|
|
|
<title><literal>login.conf</literal> file</title>
|
2009-09-24 19:35:03 +00:00
|
|
|
<para>The following configuration is a basic setup that works in Windows XP against both
|
2009-10-12 16:26:38 +00:00
|
|
|
<literal>IIS</literal> and <literal>JBoss Negotiation</literal> modules.</para>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>The system property <literal>java.security.auth.login.config</literal> can be used
|
2009-09-26 11:57:23 +00:00
|
|
|
to point at the <literal>login.conf</literal> file.</para>
|
|
|
|
<para><literal>login.conf</literal> content may look like the following:</para>
|
2009-09-13 13:21:13 +00:00
|
|
|
<programlisting><![CDATA[
|
|
|
|
com.sun.security.jgss.login {
|
|
|
|
com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
|
|
|
|
};
|
|
|
|
|
|
|
|
com.sun.security.jgss.initiate {
|
|
|
|
com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
|
|
|
|
};
|
|
|
|
|
|
|
|
com.sun.security.jgss.accept {
|
|
|
|
com.sun.security.auth.module.Krb5LoginModule required client=TRUE useTicketCache=true;
|
|
|
|
};
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</section>
|
|
|
|
<section>
|
2009-09-26 11:57:23 +00:00
|
|
|
<title><literal>krb5.conf</literal> / <literal>krb5.ini</literal> file</title>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>If unspecified, the system default will be used. Override if needed by setting the
|
|
|
|
system property <literal>java.security.krb5.conf</literal> to point to a custom
|
2009-09-26 11:57:23 +00:00
|
|
|
<literal>krb5.conf</literal> file.</para>
|
|
|
|
<para><literal>krb5.conf</literal> content may look like the following:</para>
|
2009-09-13 13:21:13 +00:00
|
|
|
<programlisting><![CDATA[
|
|
|
|
[libdefaults]
|
|
|
|
default_realm = AD.EXAMPLE.NET
|
|
|
|
udp_preference_limit = 1
|
|
|
|
[realms]
|
|
|
|
AD.EXAMPLE.NET = {
|
|
|
|
kdc = KDC.AD.EXAMPLE.NET
|
|
|
|
}
|
|
|
|
[domain_realms]
|
|
|
|
.ad.example.net=AD.EXAMPLE.NET
|
|
|
|
ad.example.net=AD.EXAMPLE.NET
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</section>
|
|
|
|
<section>
|
2009-09-26 11:57:23 +00:00
|
|
|
<title>Windows Specific configuration</title>
|
2010-12-02 01:08:08 +00:00
|
|
|
<para>To allow Windows to use the current user's tickets, the system property
|
2009-09-26 11:57:23 +00:00
|
|
|
<literal>javax.security.auth.useSubjectCredsOnly</literal> must be set to
|
2010-12-02 01:08:08 +00:00
|
|
|
<literal>false</literal> and the Windows registry key
|
2009-09-26 11:57:23 +00:00
|
|
|
<literal>allowtgtsessionkey</literal> should be added and set correctly to allow
|
|
|
|
session keys to be sent in the Kerberos Ticket-Granting Ticket.</para>
|
|
|
|
<para>On the Windows Server 2003 and Windows 2000 SP4, here is the required registry
|
|
|
|
setting:</para>
|
2009-09-13 13:21:13 +00:00
|
|
|
<programlisting><![CDATA[
|
|
|
|
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
|
|
|
|
Value Name: allowtgtsessionkey
|
|
|
|
Value Type: REG_DWORD
|
|
|
|
Value: 0x01
|
2009-09-26 11:57:23 +00:00
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
<para>Here is the location of the registry setting on Windows XP SP2:</para>
|
|
|
|
<programlisting><![CDATA[
|
2009-09-13 13:21:13 +00:00
|
|
|
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\
|
|
|
|
Value Name: allowtgtsessionkey
|
|
|
|
Value Type: REG_DWORD
|
|
|
|
Value: 0x01
|
|
|
|
]]>
|
2009-09-26 11:57:23 +00:00
|
|
|
</programlisting>
|
|
|
|
</section>
|
2009-09-13 13:21:13 +00:00
|
|
|
</section>
|
|
|
|
|
2009-07-08 19:07:17 +00:00
|
|
|
</chapter>
|