| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Chapter 4. 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 3. HTTP state management"><link rel="next" href="httpagent.html" title="Chapter 5. 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 4. HTTP authentication</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="statemgmt.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="httpagent.html">Next</a></td></tr></table><hr></div><div class="chapter" title="Chapter 4. HTTP authentication"><div class="titlepage"><div><div><h2 class="title"><a name="authentication"></a>Chapter 4. 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. User credentials"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e858"></a>4.1. 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 ></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 ></p> |
| <pre class="programlisting"> |
| DOMAIN/user |
| pwd |
| </pre> |
| </div> |
| <div class="section" title="4.2. Authentication schemes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e870"></a>4.2. 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: </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. </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: </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: </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: </b> |
| Kerberos authentication implementation. |
| </p> |
| </li></ul></div> |
| </div> |
| <div class="section" title="4.3. HTTP authentication parameters"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e912"></a>4.3. 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': </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': </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': </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': </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<String> authpref = new ArrayList<String>(); |
| authpref.add(AuthPolicy.BASIC); |
| authpref.add(AuthPolicy.DIGEST); |
| httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref); |
| </pre> |
| </div> |
| <div class="section" title="4.4. Authentication scheme registry"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e947"></a>4.4. 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: </b> |
| Basic authentication |
| </p> |
| </li><li class="listitem"> |
| <p title="AuthPolicy.DIGEST:"> |
| <b>AuthPolicy.DIGEST: </b> |
| Digest authentication |
| </p> |
| </li><li class="listitem"> |
| <p title="AuthPolicy.NTLM:"> |
| <b>AuthPolicy.NTLM: </b> |
| NTLMv1, NTLMv2, and NTLM2 Session authentication |
| </p> |
| </li><li class="listitem"> |
| <p title="AuthPolicy.SPNEGO:"> |
| <b>AuthPolicy.SPNEGO: </b> |
| SPNEGO authentication |
| </p> |
| </li><li class="listitem"> |
| <p title="AuthPolicy.KERBEROS:"> |
| <b>AuthPolicy.KERBEROS: </b> |
| Kerberos authentication |
| </p> |
| </li></ul></div> |
| </div> |
| <div class="section" title="4.5. Credentials provider"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e972"></a>4.5. 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 ></p> |
| <pre class="programlisting"> |
| [principal: u1] |
| [principal: u2] |
| null |
| [principal: u3] |
| </pre> |
| </div> |
| <div class="section" title="4.6. HTTP authentication and execution context"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e983"></a>4.6. 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': </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': </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': </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': </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': </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. Caching of authentication data"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e1029"></a>4.7. 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. Preemptive authentication"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d5e1032"></a>4.8. 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 < 3; i++) { |
| HttpResponse response = httpclient.execute(targetHost, httpget, localcontext); |
| HttpEntity entity = response.getEntity(); |
| EntityUtils.consume(entity); |
| } |
| </pre> |
| </div> |
| |
| <div class="section" title="4.9. NTLM Authentication"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ntlm"></a>4.9. 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. NTLM connection persistence"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1043"></a>4.9.1. 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. 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. SPNEGO/Kerberos Authentication"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="spnego"></a>4.10. <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 <base64 |
| encoding></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. SPNEGO support in HttpClient"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1094"></a>4.10.1. <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 >= 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. GSS/Java Kerberos Setup"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1110"></a>4.10.2. 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. login.conf file"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1118"></a>4.10.3. <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. krb5.conf / krb5.ini file"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1130"></a>4.10.4. <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. Windows Specific configuration"><div class="titlepage"><div><div><h3 class="title"><a name="d5e1140"></a>4.10.5. 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> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="httpagent.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 3. HTTP state management </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 5. HTTP client service</td></tr></table></div></body></html> |