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.

Michael

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

Reply via email to