On Wed, 2009-12-30 at 14:00 +0100, Sebastiaan van Erk wrote:
...
> Hi Oleg,
>
> I'm still working on this, just been on a bit of a break during
> Christmas, just so you know.
>
> I have a question on the effects of the following method:
>
> /**
> * Tests if the authentication scheme is provides authorization on
> a per
> * connection basis instead of usual per request basis
> *
> * @return <tt>true</tt> if the scheme is connection based,
> <tt>false</tt>
> * if the scheme is request based.
> */
> boolean isConnectionBased();
>
> According to the currently submitted implementation, the negotiate
> scheme is connection based and returns true here. However, in my tests
> with apache + mod_auth_krb, it seems that mod_auth_krb does request
> based authorization. My Squid proxy seems to do connection based auth.
>
> The problem I have is that if I want to do preemptive auth then I don't
> know how to do it on a request basis if isConnectionBased() returns
> true, because http client doesn't try to authenticate the second request
> on a connection in this case (understandably).
>
> Theoretically returning false only hurts performance, and will allow
> preemptive auth for mod_auth_krb to work.
>
> Returning true breaks non-restartable-requests (streamed post entities
> for example), because even if you authenticate the connection with a
> HEAD request or something like that, no preemptive auth is done on the
> streaming request.
>
> Maybe I'm just implementing preemptive auth wrong... What I do is add
> the following interceptors to the http client instance:
>
> private static class PreemptiveAuth implements HttpRequestInterceptor {
>
> public void process(final HttpRequest request, final
> HttpContext
> context) throws org.apache.http.HttpException, IOException {
> final AuthState httpAuthState = (AuthState)
> context.getAttribute(ClientContext.TARGET_AUTH_STATE);
> if (httpAuthState.getAuthScheme() == null) {
> final AuthScheme authScheme = (AuthScheme)
> context.getAttribute("http-preemptive-auth");
> final CredentialsProvider credsProvider =
> (CredentialsProvider)
> context.getAttribute(ClientContext.CREDS_PROVIDER);
> final HttpHost targetHost = (HttpHost)
> context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
> if (authScheme != null) {
> final Credentials creds =
> credsProvider.getCredentials(new
> AuthScope(targetHost.getHostName(), targetHost.getPort()));
> if (creds != null) {
>
> httpAuthState.setAuthScheme(authScheme);
>
> httpAuthState.setCredentials(creds);
> }
> }
> }
> }
> }
>
>
> private static class PersistentAuth implements HttpResponseInterceptor {
>
> public void process(final HttpResponse response, final
> HttpContext
> context) throws org.apache.http.HttpException, IOException {
> final AuthState httpAuthState = (AuthState)
> context.getAttribute(ClientContext.TARGET_AUTH_STATE);
> if (httpAuthState != null) {
> final AuthScheme authScheme =
> httpAuthState.getAuthScheme();
> context.setAttribute("http-preemptive-auth",
> authScheme);
> }
> }
> }
>
> So my questions basically are:
>
> 1) What to do about the fact that not all implementations seem to be
> connection based?
Simply make this configurable either through a constructor parameter or
based on the execution context.
> 2) Is there a way to send preemptive auth per request even if the scheme
> says it's connection based?
I do not think so.
Hope this helps
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]