Re: NegotiateAuth for HttpClient 4.x
Oleg, Because we required a stable version of HttpComponents, the code was based on 4.0. Doh... I should have looked at the JIRA first :) As for digging in the current docs and trunk... sorry, but I'm already promising my free time (and future free time) to everybody, so maybe some other day. Best regards Gergely Kiss Gergely, Support for SPNEGO/Kerberos authentication scheme has been recently added to the SVN trunk (See HTTPCLIENT-523 in JIRA for details). Did you base your code on 4.0 release or the latest dev snapshot? If not, it would be great if you could incorporate the latest changes into your code line and submit your enhancements as a patch against SVN trunk. There is also a fairly extensive documentation of how current SPNEGO support works in the HttpClient tutorial but you will have to generate that tutorial manually from the source code. Please also consider subscribing the the list so I would not have mod your messages in manually. Cheers Oleg - To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
Re: NegotiateAuth for HttpClient 4.x
On Wed, 2009-11-18 at 10:03 +0100, Kiss Gergely wrote:
> Dear HttpComponent Developers,
>
> We're using HttpComponents 4.x in out project for some time now, and last
> week I spent a lot of time figuring out how Exchange works with WebDAV and
> Kerberos authentication.
> In the meantime, I have implemented the NegotiateScheme class for 4.x -
> based on Mikael Wikstrom's previous work for HttpClient 3.x - which I'd like
> to contribute back to the community.
>
> Notes:
> - with 4.x it's a bit harder to add a new authentication scheme, but is
> possible with DefaultHttpClient.setTargetAuthenticationHandler() - so the
> new authPreferences should look like { "negotiate", "ntlm", "digest",
> "basic" }
> - unfortunately the current (4.0) implementation does not fall back to Basic
> or Digest if Negotiate or NTLM authentication failed, so you have to decide
> which one to use before executing the request
> - The execute() call is required to run in a JAAS context (with
> Subject.doAs(...))
> - Kerberos authentication requires a service name to work (the first part of
> the SPN), and this was a constant value ("HTTP") in the previous version -
> but the target service may already have another SPN (so registering HTTP
> would be unnecessary). For this reason, I introduced the
> parameter NegotiateSchemeFactory.SERVICE_PREFIX, which is read from the
> HttpParams specified to the client.
> - Credential delegation was tested and works very nicely
>
> Best regards
> Gergely Kiss
>
Gergely,
Support for SPNEGO/Kerberos authentication scheme has been recently
added to the SVN trunk (See HTTPCLIENT-523 in JIRA for details). Did you
base your code on 4.0 release or the latest dev snapshot? If not, it
would be great if you could incorporate the latest changes into your
code line and submit your enhancements as a patch against SVN trunk.
There is also a fairly extensive documentation of how current SPNEGO
support works in the HttpClient tutorial but you will have to generate
that tutorial manually from the source code.
Please also consider subscribing the the list so I would not have mod
your messages in manually.
Cheers
Oleg
-
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
NegotiateAuth for HttpClient 4.x
Dear HttpComponent Developers,
We're using HttpComponents 4.x in out project for some time now, and last
week I spent a lot of time figuring out how Exchange works with WebDAV and
Kerberos authentication.
In the meantime, I have implemented the NegotiateScheme class for 4.x -
based on Mikael Wikstrom's previous work for HttpClient 3.x - which I'd like
to contribute back to the community.
Notes:
- with 4.x it's a bit harder to add a new authentication scheme, but is
possible with DefaultHttpClient.setTargetAuthenticationHandler() - so the
new authPreferences should look like { "negotiate", "ntlm", "digest",
"basic" }
- unfortunately the current (4.0) implementation does not fall back to Basic
or Digest if Negotiate or NTLM authentication failed, so you have to decide
which one to use before executing the request
- The execute() call is required to run in a JAAS context (with
Subject.doAs(...))
- Kerberos authentication requires a service name to work (the first part of
the SPN), and this was a constant value ("HTTP") in the previous version -
but the target service may already have another SPN (so registering HTTP
would be unnecessary). For this reason, I introduced the
parameter NegotiateSchemeFactory.SERVICE_PREFIX, which is read from the
HttpParams specified to the client.
- Credential delegation was tested and works very nicely
Best regards
Gergely Kiss
===
NegotiateSchemeFactory.java:
===
package org.apache.http.impl.auth;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthSchemeFactory;
import org.apache.http.params.HttpParams;
/**
* Negotiate scheme factory for HttpClient 4.x.
*
* @author mailto:[email protected]";>Gergely Kiss
*/
public class NegotiateSchemeFactory implements AuthSchemeFactory {
/**
* Service prefix for the Kerberos SPN.
*
* This is HTTP by default, but some services may already have
another SPN.
*/
public static final String SERVICE_PREFIX = "KerberosServiceName";
public AuthScheme newInstance(HttpParams params) {
NegotiateScheme scheme = new NegotiateScheme();
// Setting the service prefix, if specified
Object param = params.getParameter(SERVICE_PREFIX);
if (param != null) {
scheme.setServicePrefix(String.valueOf(param));
}
return scheme;
}
}
===
NegotiateScheme.java:
===
package org.apache.http.impl.auth;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.apache.http.auth.AUTH;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.InvalidCredentialsException;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.message.BasicHeader;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
/**
* Authentication scheme implementing the Negotiate protocol with JAAS for
HTTPClient 4.x.
*
* @author mailto:[email protected]";>Mikael Wikstrom
* @author mailto:[email protected]";>Gergely Kiss
*/
public class NegotiateScheme implements AuthScheme {
/** Log object for this class. */
private static final Log log = LogFactory.getLog(NegotiateScheme.class);
private static final int UNINITIATED = 0;
private static final int INITIATED = 1;
private static final int NEGOTIATING = 3;
private static final int ESTABLISHED = 4;
private static final int FAILED = Integer.MAX_VALUE;
private GSSContext context = null;
/** Authentication process state */
private int state;
/** base64 decoded challenge * */
byte[] token = new byte[0];
/**
* Service prefix for the Kerberos SPN.
*
* This is usually HTTP, but another service name can also be
used.
*/
private String servicePrefix = "HTTP";
/**
* Default constructor for the Negotiate authentication scheme.
*
* @param subject
*
* @since 3.0
*/
public NegotiateScheme() {
super();
state = UNINITIATED;
}
/**
* Init GSSContext for negotiation.
*
* @param host servername only (e.g: radar.it.su.se)
*/
protected void init(String host) throws Exception {
log.debug("init " + host);
/* Kerberos v5 GSS-API mechanism defined in RFC 1964. */
Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
GSSManager manager = GSSManager.getInstance();
GSSName serverName = manager.createName(servicePrefix + "/" + host,
null);
context = manager.createContext(serverName,
