Oleg Kalnichevski wrote:
Oleg Kalnichevski wrote:
Sebastiaan van Erk wrote:
Oleg Kalnichevski wrote:
Sebastiaan van Erk wrote:
Hi Oleg,

Thanks for your reply.

There's a good chance I'm going to have to get this working, even if it
means I'm going to have to delve into this myself. I'll contact the
original developer and see if he sees anything obvious, but in any case, if I succeed in getting it working, I will happily contribute the patches.

Best regards,
Sebastiaan


Hi Sebastiaan

Cool. In my turn I will happily help with HttpClient specific stuff.

Hi Oleg,

I got the proxy authentication working already. I even tested it when both proxy auth and http auth are required and it works.

There is just one small issue: I need the proxy host name to generate the kerberos service name (HTTP/proxyh...@realm). The current NegotiateScheme code doesn't handle proxy auth at all and always uses the target host name which it retrieves from the Host header (is that the best way to get the target host?):

  if (isStripPort()) {

init((request.getLastHeader("Host")).getValue().replaceAll(":[0-9]+$", "") );
  } else {
    init( (request.getLastHeader("Host")).getValue());
  }

I changed the NegotiateScheme to extend AuthSchemeBase (like NTLMScheme). Now I have access to the isProxy() method and can add the correct header (Proxy-Authorization or Authorization). However, to determine the hostname I currently have this:

  String host;
  if (isProxy()) {
    // FIXME this should actually be determined by the route planner?
HttpHost proxy = ConnRouteParams.getDefaultProxy(request.getParams());
    host = proxy.getHostName();
  } else {
    host = request.getLastHeader("Host").getValue();
  }
  if (isStripPort()) {
    host = host.replaceAll(":[0-9]+$", "");
  }
  init(host);

I noticed a few frames up in DefaultRequestDirector.handleResponse the actual proxy host is known:

if (this.proxyAuthHandler.isAuthenticationRequested(response, context)) {

    HttpHost proxy = route.getProxyHost();

    this.log.debug("Proxy requested authentication");
Map<String, Header> challenges = this.proxyAuthHandler.getChallenges(response, context);
    try {
       processChallenges(challenges,
          this.proxyAuthState, this.proxyAuthHandler,
          response, context);
       } catch (AuthenticationException ex) {
    ...

But this information is not available to me at the FIXME location. I'm also ignoring any forced route now, but it seems wrong to copy paste the code from DefaultHttpRoutePlanner anyway, especially since that's just the default implementation anyhow and could be overridden.

Next thing I'll look into is why the redirect fails.

Regards,
Sebastiaan


Hi Sebastiaan

This looks nasty. The usual way of obtaining contextual details in HttpClient is by examining attributes of the HttpContext instance associated with the request being executed. The trouble is that auth schemes factories presently have no means of getting hold of the HttpContext.

One possibility of fixing it would be extending or replacing the AuthSchemeFactory with something better.

---
public interface BetterAuthSchemeFactory extends AuthSchemeFactory {

    AuthScheme newInstance(HttpContext context, HttpParams params);

}
---

This is double but is far from trivial if 100% binary compatibility with 4.0 is to be retained.

Feel free to go ahead and open a change request in JIRA for this issue.

Oleg


Probably a better alternative would be something like that

---------
/**
 * This interface represents an extended  authentication scheme
 * that requires access to {...@link HttpContext} in order to
 * generate an authorization string.
 *
 * @since 4.1
 */

public interface ContextAwareAuthScheme extends AuthScheme {

    /**
     * Produces an authorization string for the given set of
     * {...@link Credentials}.
     *
* @param credentials The set of credentials to be used for athentication
     * @param request The request being authenticated
     * @param context HTTP context
     * @throws AuthenticationException if authorization string cannot
     *   be generated due to an authentication failure
     *
     * @return the authorization string
     */
    Header authenticate(
            Credentials credentials,
            HttpRequest request,
            HttpContext context) throws AuthenticationException;

}

---------

Oleg

Hi Oleg,

The ContextAwareAuthScheme looks perfect for the job.

Should I open a JIRA issue for it?

How will binary compatibility be maintained? An instanceof check at the location where AuthScheme is used at the moment?

Regards,
Sebastiaan

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to