| <?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. |
| ==================================================================== |
| --> |
| <chapter id="authentication"> |
| <title>HTTP authentication</title> |
| <para>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 <literal>NTLM</literal> and <literal>SPNEGO</literal>.</para> |
| <section> |
| <title>User credentials</title> |
| <para>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. <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 |
| 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.</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> |
| <para>Generate the authorization string for the given set of credentials and the HTTP |
| request in response to the actual authorization challenge.</para> |
| </listitem> |
| </itemizedlist> |
| <para>Please note that authentication schemes may be stateful involving a series of |
| 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> |
| </listitem> |
| <listitem> |
| <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> |
| </listitem> |
| <listitem> |
| <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 |
| Digest.</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title>SPNEGO/Kerberos:</title> |
| <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. |
| At present HttpClient only supports the Kerberos sub-mechanism. </para> |
| </formalpara> |
| </listitem> |
| </itemizedlist> |
| </section> |
| <section> |
| <title>HTTP authentication parameters</title> |
| <para>These are parameters that be used to customize the HTTP authentication process and |
| behaviour of individual authentication schemes:</para> |
| <itemizedlist> |
| <listitem> |
| <formalpara> |
| <title><constant>ClientPNames.HANDLE_AUTHENTICATION</constant>='http.protocol.handle-authentication':</title> |
| <para>defines whether authentication should be handled automatically. This |
| parameter expects a value of type <classname>java.lang.Boolean</classname>. |
| If this parameter is not set, HttpClient will handle authentication |
| automatically.</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title><constant>AuthPNames.CREDENTIAL_CHARSET</constant>='http.auth.credential-charset':</title> |
| <para>defines the charset to be used when encoding user credentials. This |
| parameter expects a value of type <literal>java.lang.String</literal>. If |
| this parameter is not set, <literal>US-ASCII</literal> will be used.</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title><constant>AuthPNames.TARGET_AUTH_PREF</constant>='http.auth.target-scheme-pref':</title> |
| <para>Defines the order of preference for supported |
| <interfacename>AuthScheme</interfacename>s when authenticating with the |
| target host. This parameter expects a value of type |
| <interface>java.util.Collection</interface>. The collection is expected |
| to contain <classname>java.lang.String</classname> instances representing |
| an id of an authentication scheme.</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title><constant>AuthPNames.PROXY_AUTH_PREF</constant>='http.auth.proxy-scheme-pref':</title> |
| <para>Defines the order of preference for supported |
| <interfacename>AuthScheme</interfacename>s when authenticating with the |
| proxy host. This parameter expects a value of type |
| <interface>java.util.Collection</interface>. The collection is expected |
| to contain <classname>java.lang.String</classname> instances representing |
| an id of an authentication scheme.</para> |
| </formalpara> |
| </listitem> |
| </itemizedlist> |
| <para>For example, one can force HttpClient to use a different order of preference for |
| authentication schemes</para> |
| <programlisting><![CDATA[ |
| 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); |
| ]]></programlisting> |
| </section> |
| <section> |
| <title>Authentication scheme registry</title> |
| <para>HttpClient maintains a registry of available authentication schemes using |
| the <classname>AuthSchemeRegistry</classname> class. The following schemes are |
| registered per default:</para> |
| <itemizedlist> |
| <listitem> |
| <formalpara> |
| <title>AuthPolicy.BASIC:</title> |
| <para>Basic authentication</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title>AuthPolicy.DIGEST:</title> |
| <para>Digest authentication</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title>AuthPolicy.NTLM:</title> |
| <para>NTLMv1, NTLMv2, and NTLM2 Session authentication</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title>AuthPolicy.SPNEGO:</title> |
| <para>SPNEGO/Kerberos authentication</para> |
| </formalpara> |
| </listitem> |
| </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> |
| <title><constant>ClientContext.AUTHSCHEME_REGISTRY</constant>='http.authscheme-registry':</title> |
| <para><classname>AuthSchemeRegistry</classname> instance representing the actual |
| authentication scheme registry. The value of this attribute set in the local |
| context takes precedence over the default one.</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title><constant>ClientContext.CREDS_PROVIDER</constant>='http.auth.credentials-provider':</title> |
| <para><interfacename>CookieSpec</interfacename> instance representing the actual |
| credentials provider. The value of this attribute set in the local context |
| takes precedence over the default one.</para> |
| </formalpara> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title><constant>ClientContext.TARGET_AUTH_STATE</constant>='http.auth.target-scope':</title> |
| <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> |
| </listitem> |
| <listitem> |
| <formalpara> |
| <title><constant>ClientContext.PROXY_AUTH_STATE</constant>='http.auth.proxy-scope':</title> |
| <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> |
| <listitem> |
| <formalpara> |
| <title><constant>ClientContext.AUTH_CACHE</constant>='http.auth.auth-cache':</title> |
| <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> |
| </itemizedlist> |
| <para>The local <interfacename>HttpContext</interfacename> 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:</para> |
| <programlisting><![CDATA[ |
| 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 scope: " + proxyAuthState.getAuthScope()); |
| 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 scope: " + targetAuthState.getAuthScope()); |
| System.out.println("Target auth scheme: " + targetAuthState.getAuthScheme()); |
| System.out.println("Target auth credentials: " + targetAuthState.getCredentials()); |
| ]]></programlisting> |
| </section> |
| <section> |
| <title>Caching of authentication data</title> |
| <para>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.</para> |
| </section> |
| <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 |
| environment.</para> |
| <para>Nonethess one can configure HttpClient to authenticate preemptively by prepopulating |
| the authentication data cache.</para> |
| <programlisting><![CDATA[ |
| 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); |
| } |
| ]]></programlisting> |
| </section> |
| |
| <section id="ntlm"> |
| <title>NTLM Authentication</title> |
| <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 |
| <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> |
| project as a part of their Windows interoperability suite of programs. |
| </para> |
| <section> |
| <title>NTLM connection persistence</title> |
| <para>The <literal>NTLM</literal> authentication scheme is significantly more expensive |
| 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> |
| <!-- Note: the stateful_conn anchor is in the file advanced.xml --> |
| <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[ |
| 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); |
| ]]></programlisting> |
| </section> |
| </section> |
| |
| <section id="spnego"> |
| <title><literal>SPNEGO</literal>/Kerberos Authentication</title> |
| <para>The <literal>SPNEGO</literal> (<emphasis>S</emphasis>imple and |
| <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 |
| in HttpClient is designed solely with Kerberos in mind. </para> |
| <sidebar> |
| <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> |
| </sidebar> |
| <section> |
| <title><literal>SPNEGO</literal> support in HttpClient</title> |
| <para>The <literal>SPNEGO</literal> 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 <literal>SPNEGO</literal> authentication more completely.</para> |
| <para>The Sun JRE provides the supporting classes to do nearly all the Kerberos and |
| <literal>SPNEGO</literal> token handling. This means that a lot of the setup is |
| for the GSS classes. The <classname>NegotiateScheme</classname> is a simple class to |
| 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 |
| happen but if lucky it'll work without too much of a problem. It should also provide some |
| output to debug with.</para> |
| |
| <para>In Windows it should default to using the logged in credentials; this can be |
| overridden by using 'kinit' e.g. <literal>$JAVA_HOME\bin\kinit |
| testuser@AD.EXAMPLE.NET</literal>, which is very helpful for testing and |
| debugging issues. Remove the cache file created by kinit to revert back to the windows |
| Kerberos cache.</para> |
| <para>Make sure to list <literal>domain_realms</literal> in the |
| <literal>krb5.conf</literal> file. This is a major source of problems.</para> |
| </section> |
| <section> |
| <title>GSS/Java Kerberos Setup</title> |
| <para>This documentation assumes you are using Windows but much of the information |
| 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 |
| 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> |
| </section> |
| <section> |
| <title><literal>login.conf</literal> file</title> |
| <para>The following configuration is a basic setup that works in Windows XP against both |
| <literal>IIS</literal> and <literal>JBoss Negotiation</literal> modules.</para> |
| <para>The system property <literal>java.security.auth.login.config</literal> can be used |
| to point at the <literal>login.conf</literal> file.</para> |
| <para><literal>login.conf</literal> content may look like the following:</para> |
| <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> |
| <title><literal>krb5.conf</literal> / <literal>krb5.ini</literal> file</title> |
| <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 |
| <literal>krb5.conf</literal> file.</para> |
| <para><literal>krb5.conf</literal> content may look like the following:</para> |
| <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> |
| <title>Windows Specific configuration</title> |
| <para>To allow Windows to use the current user's tickets, the system property |
| <literal>javax.security.auth.useSubjectCredsOnly</literal> must be set to |
| <literal>false</literal> and the Windows registry key |
| <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> |
| <programlisting><![CDATA[ |
| HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters |
| Value Name: allowtgtsessionkey |
| Value Type: REG_DWORD |
| Value: 0x01 |
| ]]> |
| </programlisting> |
| <para>Here is the location of the registry setting on Windows XP SP2:</para> |
| <programlisting><![CDATA[ |
| HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\ |
| Value Name: allowtgtsessionkey |
| Value Type: REG_DWORD |
| Value: 0x01 |
| ]]> |
| </programlisting> |
| </section> |
| <section> |
| <title>Customizing <literal>SPNEGO</literal> authentication scheme</title> |
| <para>In order to customize <literal>SPNEGO</literal> support a new instance of |
| the <classname>NegotiateSchemeFactory</classname> class must be created and |
| registered with the authentication scheme registry of HttpClient. </para> |
| <programlisting><![CDATA[ |
| DefaultHttpClient httpclient = new DefaultHttpClient(); |
| NegotiateSchemeFactory nsf = new NegotiateSchemeFactory(); |
| httpclient.getAuthSchemes().register(AuthPolicy.SPNEGO, nsf); |
| ]]> |
| </programlisting> |
| <para>There are several options that can be used to customize the behaviour of |
| <classname>NegotiateSchemeFactory</classname>. </para> |
| <section> |
| <title>Strip port</title> |
| <para>Strips the port off service names e.g. |
| <literal>HTTP/webserver.ad.example.net:8080</literal> -> |
| <literal>HTTP/webserver.ad.example.net</literal></para> |
| <para>Found it useful when authenticating against JBoss Negotiation.</para> |
| </section> |
| <section> |
| <title>Custom <literal>SPNEGO</literal> token generator</title> |
| <para>Use this method to inject a custom |
| <interfacename>SpnegoTokenGenerator</interfacename> class to do the Kerberos |
| to <literal>SPNEGO</literal> token wrapping. |
| The <classname>BouncySpnegoTokenGenerator</classname> implementation is provided |
| as an unsupported contribution from the contrib package. This requires the |
| BouncyCastle libraries <ulink url="http://www.bouncycastle.org/java.html" |
| >"http://www.bouncycastle.org/java.html"</ulink>. Found especially useful |
| when using Java 1.5, which is known to provide only a limited support for |
| <literal>SPNEGO</literal> authentication. |
| </para> |
| </section> |
| </section> |
| </section> |
| |
| </chapter> |