blob: 5d73ad0d01ef9becc0c2da968b837ab01eae91b5 [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter&nbsp;4.&nbsp;HTTP authentication</title><link rel="stylesheet" type="text/css" href="css/hc-tutorial.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><link rel="home" href="index.html" title="HttpClient Tutorial"><link rel="up" href="index.html" title="HttpClient Tutorial"><link rel="prev" href="statemgmt.html" title="Chapter&nbsp;3.&nbsp;HTTP state management"><link rel="next" href="httpagent.html" title="Chapter&nbsp;5.&nbsp;HTTP client service"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="banner"><a class="bannerLeft" href="http://www.apache.org/" title="Apache Software Foundation"><img style="border:none;" src="images/asf_logo_wide.gif"></a><a class="bannerRight" href="http://hc.apache.org/httpcomponents-client-ga/" title="Apache HttpComponents Client"><img style="border:none;" src="images/hc_logo.png"></a><div class="clear"></div></div><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter&nbsp;4.&nbsp;HTTP authentication</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="statemgmt.html">Prev</a>&nbsp;</td><th width="60%" align="center">&nbsp;</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="httpagent.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter&nbsp;4.&nbsp;HTTP authentication"><div class="titlepage"><div><div><h2 class="title"><a name="authentication"></a>Chapter&nbsp;4.&nbsp;HTTP authentication</h2></div></div></div>
<p>HttpClient provides full support for authentication schemes defined by the HTTP standard
specification as well as a number of widely used non-standard authentication schemes such
as <code class="literal">NTLM</code> and <code class="literal">SPNEGO</code>.</p>
<div class="section" title="4.1.&nbsp;User credentials"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e858"></a>4.1.&nbsp;User credentials</h2></div></div></div>
<p>Any process of user authentication requires a set of credentials that can be used to
establish user identity. In the simplest form user credentials can be just a user name /
password pair. <code class="classname">UsernamePasswordCredentials</code> 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.</p>
<pre class="programlisting">
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
user
pwd
</pre>
<p><code class="classname">NTCredentials</code> is a Microsoft Windows specific implementation
that includes in addition to the user name / password pair a set of additional Windows
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
authorizations.</p>
<pre class="programlisting">
NTCredentials creds = new NTCredentials("user", "pwd", "workstation", "domain");
System.out.println(creds.getUserPrincipal().getName());
System.out.println(creds.getPassword());
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
DOMAIN/user
pwd
</pre>
</div>
<div class="section" title="4.2.&nbsp;Authentication schemes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e870"></a>4.2.&nbsp;Authentication schemes</h2></div></div></div>
<p>The <code class="interfacename">AuthScheme</code> interface represents an abstract
challenge-response oriented authentication scheme. An authentication scheme is expected
to support the following functions:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p>Parse and process the challenge sent by the target server in response to
request for a protected resource.</p>
</li><li class="listitem">
<p>Provide properties of the processed challenge: the authentication scheme type
and its parameters, such the realm this authentication scheme is applicable to,
if available</p>
</li><li class="listitem">
<p>Generate the authorization string for the given set of credentials and the HTTP
request in response to the actual authorization challenge.</p>
</li></ul></div>
<p>Please note that authentication schemes may be stateful involving a series of
challenge-response exchanges.</p>
<p>HttpClient ships with several <code class="interfacename">AuthScheme</code>
implementations:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p title="Basic:">
<b>Basic:&nbsp;</b>
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.
</p>
</li><li class="listitem">
<p title="Digest">
<b>Digest.&nbsp;</b>
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.
</p>
</li><li class="listitem">
<p title="NTLM:">
<b>NTLM:&nbsp;</b>
NTLM is a proprietary authentication scheme developed by Microsoft and
optimized for Windows platforms. NTLM is believed to be more secure than
Digest.
</p>
</li><li class="listitem">
<p title="SPNEGO:">
<b>SPNEGO:&nbsp;</b>
<code class="literal">SPNEGO</code> (<span class="emphasis"><em>S</em></span>imple and
<span class="emphasis"><em>P</em></span>rotected <code class="literal">GSSAPI</code>
<span class="emphasis"><em>Nego</em></span>tiation Mechanism) is a <code class="literal">GSSAPI</code>
"pseudo mechanism" that is used to negotiate one of a number of possible
real mechanisms. SPNEGO's most visible use is in Microsoft's <code class="literal">HTTP
Negotiate</code> authentication extension. The negotiable
sub-mechanisms include NTLM and Kerberos supported by Active Directory.
At present HttpClient only supports the Kerberos sub-mechanism.
</p>
</li><li class="listitem">
<p title="Kerberos:">
<b>Kerberos:&nbsp;</b>
Kerberos authentication implementation.
</p>
</li></ul></div>
</div>
<div class="section" title="4.3.&nbsp;HTTP authentication parameters"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e912"></a>4.3.&nbsp;HTTP authentication parameters</h2></div></div></div>
<p>These are parameters that be used to customize the HTTP authentication process and
behaviour of individual authentication schemes:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p title="ClientPNames.HANDLE_AUTHENTICATION='http.protocol.handle-authentication':">
<b><code class="constant">ClientPNames.HANDLE_AUTHENTICATION</code>='http.protocol.handle-authentication':&nbsp;</b>
defines whether authentication should be handled automatically. This
parameter expects a value of type <code class="classname">java.lang.Boolean</code>.
If this parameter is not set, HttpClient will handle authentication
automatically.
</p>
</li><li class="listitem">
<p title="AuthPNames.CREDENTIAL_CHARSET='http.auth.credential-charset':">
<b><code class="constant">AuthPNames.CREDENTIAL_CHARSET</code>='http.auth.credential-charset':&nbsp;</b>
defines the charset to be used when encoding user credentials. This
parameter expects a value of type <code class="literal">java.lang.String</code>. If
this parameter is not set, <code class="literal">US-ASCII</code> will be used.
</p>
</li><li class="listitem">
<p title="AuthPNames.TARGET_AUTH_PREF='http.auth.target-scheme-pref':">
<b><code class="constant">AuthPNames.TARGET_AUTH_PREF</code>='http.auth.target-scheme-pref':&nbsp;</b>
Defines the order of preference for supported
<code class="interfacename">AuthScheme</code>s when authenticating with the
target host. This parameter expects a value of type
<span class="interface">java.util.Collection</span>. The collection is expected
to contain <code class="classname">java.lang.String</code> instances representing
an id of an authentication scheme.
</p>
</li><li class="listitem">
<p title="AuthPNames.PROXY_AUTH_PREF='http.auth.proxy-scheme-pref':">
<b><code class="constant">AuthPNames.PROXY_AUTH_PREF</code>='http.auth.proxy-scheme-pref':&nbsp;</b>
Defines the order of preference for supported
<code class="interfacename">AuthScheme</code>s when authenticating with the
proxy host. This parameter expects a value of type
<span class="interface">java.util.Collection</span>. The collection is expected
to contain <code class="classname">java.lang.String</code> instances representing
an id of an authentication scheme.
</p>
</li></ul></div>
<p>For example, one can force HttpClient to use a different order of preference for
authentication schemes</p>
<pre class="programlisting">
DefaultHttpClient httpclient = new DefaultHttpClient(ccm, params);
// Choose BASIC over DIGEST for proxy authentication
List&lt;String&gt; authpref = new ArrayList&lt;String&gt;();
authpref.add(AuthPolicy.BASIC);
authpref.add(AuthPolicy.DIGEST);
httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref);
</pre>
</div>
<div class="section" title="4.4.&nbsp;Authentication scheme registry"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e947"></a>4.4.&nbsp;Authentication scheme registry</h2></div></div></div>
<p>HttpClient maintains a registry of available authentication schemes using
the <code class="classname">AuthSchemeRegistry</code> class. The following schemes are
registered per default:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p title="AuthPolicy.BASIC:">
<b>AuthPolicy.BASIC:&nbsp;</b>
Basic authentication
</p>
</li><li class="listitem">
<p title="AuthPolicy.DIGEST:">
<b>AuthPolicy.DIGEST:&nbsp;</b>
Digest authentication
</p>
</li><li class="listitem">
<p title="AuthPolicy.NTLM:">
<b>AuthPolicy.NTLM:&nbsp;</b>
NTLMv1, NTLMv2, and NTLM2 Session authentication
</p>
</li><li class="listitem">
<p title="AuthPolicy.SPNEGO:">
<b>AuthPolicy.SPNEGO:&nbsp;</b>
SPNEGO authentication
</p>
</li><li class="listitem">
<p title="AuthPolicy.KERBEROS:">
<b>AuthPolicy.KERBEROS:&nbsp;</b>
Kerberos authentication
</p>
</li></ul></div>
</div>
<div class="section" title="4.5.&nbsp;Credentials provider"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e972"></a>4.5.&nbsp;Credentials provider</h2></div></div></div>
<p>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.</p>
<p>HttpClient can work with any physical representation of a credentials provider that
implements the <code class="interfacename">CredentialsProvider</code> interface. The default
<code class="interfacename">CredentialsProvider</code> implementation called
<code class="classname">BasicCredentialsProvider</code> is a simple implementation backed by
a <code class="classname">java.util.HashMap</code>.</p>
<pre class="programlisting">
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")));
</pre>
<p>stdout &gt;</p>
<pre class="programlisting">
[principal: u1]
[principal: u2]
null
[principal: u3]
</pre>
</div>
<div class="section" title="4.6.&nbsp;HTTP authentication and execution context"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e983"></a>4.6.&nbsp;HTTP authentication and execution context</h2></div></div></div>
<p>HttpClient relies on the <code class="classname">AuthState</code> class to keep track of
detailed information about the state of the authentication process. HttpClient creates
two instances of <code class="classname">AuthState</code> 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
<code class="classname">AuthScope</code> instance will be populated with the
<code class="classname">AuthScope</code>, <code class="interfacename">AuthScheme</code> and
<code class="interfacename">Crednetials</code> used during the authentication process.
The <code class="classname">AuthState</code> can be examined in order to find out what kind of
authentication was requested, whether a matching
<code class="interfacename">AuthScheme</code> implementation was found and whether the
credentials provider managed to find user credentials for the given authentication
scope.</p>
<p>In the course of HTTP request execution HttpClient adds the following authentication
related objects to the execution context:</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p title="ClientContext.AUTHSCHEME_REGISTRY='http.authscheme-registry':">
<b><code class="constant">ClientContext.AUTHSCHEME_REGISTRY</code>='http.authscheme-registry':&nbsp;</b>
<code class="classname">AuthSchemeRegistry</code> instance representing the actual
authentication scheme registry. The value of this attribute set in the local
context takes precedence over the default one.
</p>
</li><li class="listitem">
<p title="ClientContext.CREDS_PROVIDER='http.auth.credentials-provider':">
<b><code class="constant">ClientContext.CREDS_PROVIDER</code>='http.auth.credentials-provider':&nbsp;</b>
<code class="interfacename">CookieSpec</code> instance representing the actual
credentials provider. The value of this attribute set in the local context
takes precedence over the default one.
</p>
</li><li class="listitem">
<p title="ClientContext.TARGET_AUTH_STATE='http.auth.target-scope':">
<b><code class="constant">ClientContext.TARGET_AUTH_STATE</code>='http.auth.target-scope':&nbsp;</b>
<code class="classname">AuthState</code> instance representing the actual target
authentication state. The value of this attribute set in the local context
takes precedence over the default one.
</p>
</li><li class="listitem">
<p title="ClientContext.PROXY_AUTH_STATE='http.auth.proxy-scope':">
<b><code class="constant">ClientContext.PROXY_AUTH_STATE</code>='http.auth.proxy-scope':&nbsp;</b>
<code class="classname">AuthState</code> instance representing the actual proxy
authentication state. The value of this attribute set in the local context
takes precedence over the default one.
</p>
</li><li class="listitem">
<p title="ClientContext.AUTH_CACHE='http.auth.auth-cache':">
<b><code class="constant">ClientContext.AUTH_CACHE</code>='http.auth.auth-cache':&nbsp;</b>
<code class="interfacename">AuthCache</code> instance representing the actual
authentication data cache. The value of this attribute set in the local
context takes precedence over the default one.
</p>
</li></ul></div>
<p>The local <code class="interfacename">HttpContext</code> object can be used to customize
the HTTP authentication context prior to request execution, or to examine its state after
the request has been executed:</p>
<pre class="programlisting">
HttpClient httpclient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpget = new HttpGet("http://localhost:8080/");
HttpResponse response = httpclient.execute(httpget, localContext);
AuthState proxyAuthState = (AuthState) localContext.getAttribute(
ClientContext.PROXY_AUTH_STATE);
System.out.println("Proxy auth state: " + proxyAuthState.getState());
System.out.println("Proxy auth scheme: " + proxyAuthState.getAuthScheme());
System.out.println("Proxy auth credentials: " + proxyAuthState.getCredentials());
AuthState targetAuthState = (AuthState) localContext.getAttribute(
ClientContext.TARGET_AUTH_STATE);
System.out.println("Target auth state: " + targetAuthState.getState());
System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme());
System.out.println("Target auth credentials: " + targetAuthState.getCredentials());
</pre>
</div>
<div class="section" title="4.7.&nbsp;Caching of authentication data"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e1029"></a>4.7.&nbsp;Caching of authentication data</h2></div></div></div>
<p>As of version 4.1 HttpClient automatically caches information about hosts it has
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.</p>
</div>
<div class="section" title="4.8.&nbsp;Preemptive authentication"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e1032"></a>4.8.&nbsp;Preemptive authentication</h2></div></div></div>
<p>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
environment.</p>
<p>Nonethess one can configure HttpClient to authenticate preemptively by prepopulating
the authentication data cache.</p>
<pre class="programlisting">
HttpHost targetHost = new HttpHost("localhost", 80, "http");
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(targetHost.getHostName(), targetHost.getPort()),
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
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
HttpGet httpget = new HttpGet("/");
for (int i = 0; i &lt; 3; i++) {
HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
}
</pre>
</div>
<div class="section" title="4.9.&nbsp;NTLM Authentication"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ntlm"></a>4.9.&nbsp;NTLM Authentication</h2></div></div></div>
<p>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
<code class="literal">NTLM</code> engine such as <a class="ulink" href="http://jcifs.samba.org/" target="_top">JCIFS
</a> library developed by the <a class="ulink" href="http://www.samba.org/" target="_top">Samba</a>
project as a part of their Windows interoperability suite of programs.
</p>
<div class="section" title="4.9.1.&nbsp;NTLM connection persistence"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1043"></a>4.9.1.&nbsp;NTLM connection persistence</h3></div></div></div>
<p>The <code class="literal">NTLM</code> authentication scheme is significantly more expensive
in terms of computational overhead and performance impact than the standard
<code class="literal">Basic</code> and <code class="literal">Digest</code> schemes. This is likely to be
one of the main reasons why Microsoft chose to make <code class="literal">NTLM</code>
authentication scheme stateful. That is, once authenticated, the user identity is
associated with that connection for its entire life span. The stateful nature of
<code class="literal">NTLM</code> connections makes connection persistence more complex, as
for the obvious reason persistent <code class="literal">NTLM</code> 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 <code class="literal">NTLM</code> protected resources. For detailed
discussion on stateful HTTP connections please refer to
<a class="link" href="advanced.html#stateful_conn" title="8.2.&nbsp;Stateful HTTP connections">this </a> section. </p>
<p>As <code class="literal">NTLM</code> connections are stateful it is generally recommended
to trigger <code class="literal">NTLM</code> authentication using a relatively cheap method,
such as <code class="literal">GET</code> or <code class="literal">HEAD</code>, and re-use the same
connection to execute more expensive methods, especially those enclose a request
entity, such as <code class="literal">POST</code> or <code class="literal">PUT</code>. </p>
<pre class="programlisting">
DefaultHttpClient httpclient = new DefaultHttpClient();
NTCredentials creds = new NTCredentials("user", "pwd", "myworkstation", "microsoft.com");
httpclient.getCredentialsProvider().setCredentials(AuthScope.ANY, creds);
HttpHost target = new HttpHost("www.microsoft.com", 80, "http");
// Make sure the same context is used to execute logically related requests
HttpContext localContext = new BasicHttpContext();
// Execute a cheap method first. This will trigger NTLM authentication
HttpGet httpget = new HttpGet("/ntlm-protected/info");
HttpResponse response1 = httpclient.execute(target, httpget, localContext);
HttpEntity entity1 = response1.getEntity();
EntityUtils.consume(entity1);
// 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"));
HttpResponse response2 = httpclient.execute(target, httppost, localContext);
HttpEntity entity2 = response2.getEntity();
EntityUtils.consume(entity2);
</pre>
</div>
</div>
<div class="section" title="4.10.&nbsp;SPNEGO/Kerberos Authentication"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spnego"></a>4.10.&nbsp;<code class="literal">SPNEGO</code>/Kerberos Authentication</h2></div></div></div>
<p>The <code class="literal">SPNEGO</code> (<span class="emphasis"><em>S</em></span>imple and
<span class="emphasis"><em>P</em></span>rotected <code class="literal">GSSAPI</code>
<span class="emphasis"><em>Nego</em></span>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
in HttpClient is designed solely with Kerberos in mind. </p>
<div class="sidebar"><div class="titlepage"></div>
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p>Client Web Browser does HTTP GET for resource.</p>
</li><li class="listitem">
<p>Web server returns HTTP 401 status and a header:
<code class="literal">WWW-Authenticate: Negotiate</code></p>
</li><li class="listitem">
<p>Client generates a <code class="literal">NegTokenInit</code>, base64 encodes it, and
resubmits the <code class="literal">GET</code> with an Authorization header:
<code class="literal">Authorization: Negotiate &lt;base64
encoding&gt;</code>.</p>
</li><li class="listitem">
<p>Server decodes the <code class="literal">NegTokenInit</code>, extracts the supported
<code class="literal">MechTypes</code> (only Kerberos V5 in our case), ensures it
is one of the expected ones, and then extracts the
<code class="literal">MechToken</code> (Kerberos Token) and authenticates
it.</p>
<p>If more processing is required another HTTP 401 is returned to the client
with more data in the the <code class="literal">WWW-Authenticate</code> header. Client
takes the info and generates another token passing this back in the
<code class="literal">Authorization</code> header until complete.</p>
</li><li class="listitem">
<p>When the client has been authenticated the Web server should return the
HTTP 200 status, a final <code class="literal">WWW-Authenticate</code> header and the
page content.</p>
</li></ol></div>
</div>
<div class="section" title="4.10.1.&nbsp;SPNEGO support in HttpClient"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1094"></a>4.10.1.&nbsp;<code class="literal">SPNEGO</code> support in HttpClient</h3></div></div></div>
<p>The <code class="literal">SPNEGO</code> authentication scheme is compatible with Sun Java
versions 1.5 and up. However the use of Java &gt;= 1.6 is strongly recommended as it
supports <code class="literal">SPNEGO</code> authentication more completely.</p>
<p>The Sun JRE provides the supporting classes to do nearly all the Kerberos and
<code class="literal">SPNEGO</code> token handling. This means that a lot of the setup is
for the GSS classes. The <code class="classname">SPNegoScheme</code> is a simple class to
handle marshalling the tokens and reading and writing the correct headers.</p>
<p>The best way to start is to grab the <code class="literal">KerberosHttpClient.java</code>
file in examples and try and get it to work. There are a lot of issues that can
happen but if lucky it'll work without too much of a problem. It should also provide some
output to debug with.</p>
<p>In Windows it should default to using the logged in credentials; this can be
overridden by using 'kinit' e.g. <code class="literal">$JAVA_HOME\bin\kinit
testuser@AD.EXAMPLE.NET</code>, which is very helpful for testing and
debugging issues. Remove the cache file created by kinit to revert back to the windows
Kerberos cache.</p>
<p>Make sure to list <code class="literal">domain_realms</code> in the
<code class="literal">krb5.conf</code> file. This is a major source of problems.</p>
</div>
<div class="section" title="4.10.2.&nbsp;GSS/Java Kerberos Setup"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1110"></a>4.10.2.&nbsp;GSS/Java Kerberos Setup</h3></div></div></div>
<p>This documentation assumes you are using Windows but much of the information
applies to Unix as well.</p>
<p>The <code class="classname">org.ietf.jgss</code> classes have lots of possible
configuration parameters, mainly in the
<code class="literal">krb5.conf</code>/<code class="literal">krb5.ini</code> file. Some more info on
the format at <a class="ulink" href="http://web.mit.edu/kerberos/krb5-1.4/krb5-1.4.1/doc/krb5-admin/krb5.conf.html" target="_top">http://web.mit.edu/kerberos/krb5-1.4/krb5-1.4.1/doc/krb5-admin/krb5.conf.html</a>.</p>
</div>
<div class="section" title="4.10.3.&nbsp;login.conf file"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1118"></a>4.10.3.&nbsp;<code class="literal">login.conf</code> file</h3></div></div></div>
<p>The following configuration is a basic setup that works in Windows XP against both
<code class="literal">IIS</code> and <code class="literal">JBoss Negotiation</code> modules.</p>
<p>The system property <code class="literal">java.security.auth.login.config</code> can be used
to point at the <code class="literal">login.conf</code> file.</p>
<p><code class="literal">login.conf</code> content may look like the following:</p>
<pre class="programlisting">
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;
};
</pre>
</div>
<div class="section" title="4.10.4.&nbsp;krb5.conf / krb5.ini file"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1130"></a>4.10.4.&nbsp;<code class="literal">krb5.conf</code> / <code class="literal">krb5.ini</code> file</h3></div></div></div>
<p>If unspecified, the system default will be used. Override if needed by setting the
system property <code class="literal">java.security.krb5.conf</code> to point to a custom
<code class="literal">krb5.conf</code> file.</p>
<p><code class="literal">krb5.conf</code> content may look like the following:</p>
<pre class="programlisting">
[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
</pre>
</div>
<div class="section" title="4.10.5.&nbsp;Windows Specific configuration"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1140"></a>4.10.5.&nbsp;Windows Specific configuration</h3></div></div></div>
<p>To allow Windows to use the current user's tickets, the system property
<code class="literal">javax.security.auth.useSubjectCredsOnly</code> must be set to
<code class="literal">false</code> and the Windows registry key
<code class="literal">allowtgtsessionkey</code> should be added and set correctly to allow
session keys to be sent in the Kerberos Ticket-Granting Ticket.</p>
<p>On the Windows Server 2003 and Windows 2000 SP4, here is the required registry
setting:</p>
<pre class="programlisting">
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01
</pre>
<p>Here is the location of the registry setting on Windows XP SP2:</p>
<pre class="programlisting">
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01
</pre>
</div>
</div>
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="statemgmt.html">Prev</a>&nbsp;</td><td width="20%" align="center">&nbsp;</td><td width="40%" align="right">&nbsp;<a accesskey="n" href="httpagent.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;3.&nbsp;HTTP state management&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;5.&nbsp;HTTP client service</td></tr></table></div></body></html>