hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Osipov <micha...@apache.org>
Subject Re: Need clarification on the auth backend design for HTTPCLIENT-1625
Date Fri, 13 Mar 2015 14:49:59 GMT
Hi Oleg,

finally I am able to respond. Way too late. A cold has knocked me off 
for 10 days.

Am 2015-03-03 um 18:54 schrieb Oleg Kalnichevski:
> On Tue, 2015-03-03 at 08:15 +0100, Michael Osipov wrote:
>> Am 2015-03-02 um 12:31 schrieb Oleg Kalnichevski:
>>> On Sun, 2015-03-01 at 22:45 +0100, Michael Osipov wrote:
>>>> Hi folks,
>>>> I need some design clarification on the HttpClient auth backend.
>>>> Currently, I trying to figure out how I can plug in connection-based
>>>> auth best into the code. From reading the docs and the code, this is
>>>> what I understood now:
>>>> Client receives a 401/407, looks up the best available
>>>> AuthSchemeProvider for that. This one creates a scheme implementation
>>>> instance which does all the hard work.
>>>> Given that I have a connection-based auth, I need to be sure that the
>>>> created instance is maintained on the HTTP connection, refed on the same
>>>> connection when I receive the mutual response from the server back and
>>>> then finally disposed (important) when I return isCompleted == true.
>>>> This instance is internally stateful and must be stateful. It must also
>>>> disposed when the authentication has failed for some reason.
>>>> I am quite confused by AuthProtocolState and HttpAuthenticator. Latter
>>>> retains an auth state with the former but I cannot set the former from
>>>> within my authenticator. Is that opaque to me and I should solely rely
>>>> on setting isConnectionBased?
>>> Yes, you should.
>>>> In other words: I need to create a GSSContext which is stateful on the
>>>> HTTP connection and has to be maintained until the context has been
>>>> successfully established. After that, I have to dispose it explicitly
>>>> and HttpClient must throw away the scheme instance around that. If
>>>> further request arrive on that connection later on a new scheme instance
>>>> must be created by the backend. So, does it simply suffice to implement
>>>> ContextAwareAuthScheme, AuthSchemeProvider and AuthSchemeBase properly?
>>> Yes, it does. This works with NTLM which is connection-based, stateful
>>> and involves multiple auth handshakes. It should also work for GSS
>>> auth.
>> Awesome, both sound just the way I need it.
>> Just to be clear: AuthScheme instance is nulled and GCed as soon as auth
>> fails or succeeds?
> No, they are not. They gets GCed only when the HttpContext instance used
> to execute the exchange gets out of scope. However AuthScheme
> implementations can deallocate resources immediately upon completion of
> its part of the handshake (either in case of success or failure).

OK. That is valuable information. I will maintain an internal state and 
will reset the AuthScheme impl as soon as authentication has either 
succeeded or failed.

>> I do not need to cache my GSSContext in the
>> HttpContext?
> I do not think so.
>> What about the UserTokenHandler? Do I need to provide some
>> principal back after successful auth, if yes how do I pass that?
> The user identity / security principal used by GSS represents the
> authenticated (logged on) user and essentially applies to all
> connections open by the user, does not it? Can one create an instance of
> GSSContext with a different user principal or is it always the same
> authenticated (logged on) user? If not, persistent connections cannot be
> accidentally re-used by someone with a different user identity /
> security principal and as far as HttpClient is concerned are state-less.

It is not always that clear. Let me explain why: if we say that the 
authentication is connection-bound, we still have no clue -- and 
shouldn't make any assumptions -- how the server internally maintains 
that information. The server (e.g. IIS) can/will bind against the HTTP 
connection and won't bother again until the connection is disposed. 
Where as in Tomcat (connection object is not available in a valve) will 
re-authenticate every single request roundtrip. So, I will not make any 
assumptions about it but simply respond to the server as soon as it will 
require me to. To answer the first question, yes it does apply if the 
server does so.

To answer the second question, I'd like to sketch a usecase for which I 
want to provide a proper implementation: Webapp running on a Servlet 
Container, requesting some resources on a backend system. A connection 
pool to the client has been added. All resources are accessed with the 
default system account on that machine (e.g., /etc/krb5.keytab). Now, in 
some cases you have your webapp protected by SPNEGO too and the client 
sends you his ticket along with his delegated credential. What you can 
do now is to re-use his GSSCredential and execute a request on behalf of 
the user with a previously authenticated connection on the backend 
server. Since the pool is opaque to the controller in the webapp, you 
won't notice. If the server won't prompt you, you won't authentiate 
anyway. To answer the second question, yes you can have arbitrary 
GSSCredentials perform any requests which you might decide at runtime. 
Karl Wright even depicted that usecase in his very first mail when I 
introduced myself.

I do not know now how to solve this cleanly but I'd rather face this 
edgecase when someone files an issue. I will test at work as good as I 
can against IIS, Apache HTTPd and Tomcat. Luckily, HTTP connection are, 
in most cases, not as longlived as database connections.


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

View raw message