hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oleg Kalnichevski <ol...@apache.org>
Subject Re: Kerberos proxy authentication issue
Date Fri, 11 Dec 2009 22:52:28 GMT
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/proxyhost@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

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org


Mime
View raw message