Hi all,
I am currently trying to make the authentication in HttpConduit more
flexible.
In the following thread I already discussed with Dan to use a strategy
pattern:
http://cxf.547215.n5.nabble.com/Re-Discuss-change-http-authorization-handling-to-be-strategy-based-td3266405.html#none
So my current goals / requirements are:
1) Move as much auth stuff out of HttpConduit as possible
2) Handle proxy authentication and server authentication in the same way
3) The authentication implementations should not know too much of their
environment. (Currently the calls on HttpAuthSupplier use HttpConduit
and Message which is too much knowledge in my opinion)
4) Configuration handling and overrides should be outside of the
mechansim implementation if possible. So for example today the
DigestAuthSupplier decides if it uses the config from the conduit or the
message.
5) The authentication support should be flexible enough for challenge
based authentications like NTLM that need several challenge/response
exchanges
6) The authentication should support streaming whenever possible
7) Basic auth should be easy to setup
8) Only one mechanism will be set up in the config per conduit. It is
not necessary to have several in parallel with fallbacks
These goals are not possible to achieve with the current
HttpAuthSupplier interface.
So my first question is: How important is the current HttpAuthSupplier
interface? Is it ok to change it? Do we need a deprecation phase?
The other topic is to discuss my idea for a interface. I have attached
my design below.
The idea is to have a HttpClientAuthenticationProvider imlementation
that is selected by the mechanism name it supports. The implementation
will be
instantiated by conduit (no singleton so it can hold authentication
state). The AuthenticationProvider delegates finding the username
password combination
to use to a CredentialsProvider. The simplest form is a provider that
always delivers the same username and password and is configured from
AuthorizationPolicy of conduit.
I would be happy to hear some opinions and suggestions about the design.
Currently the design does not support our complicated override
possibilities. I have digged into the HttpConduit and found that
authorization information is currently drawn from the following sources:
- HttpConduit.authSupplier => only for server authentication
- HttpConduit.authorizationPolicy => for server authentication
- HttpConduit.proxyAuthorizationPolicy
- Message.AuthorizationPolicy => only for server auth, overrides conduit
authorizationPolicy
- Message.AUTH_VALUE => not exactly sure when this is used
- Message.AuthorizationPolicy.authorization => is used if set and no
username is given
I think this opens much too many possible ways to configure
authentication and I doubt that any user really understands when which
config is used. Still these ways can be configured today and I have no
idea how many
people use each style. For example the Negotiate / Kerberos
implementation I found on the net uses the last option.
So my question is do we need all these possible ways of configuration?
Best regards
Christian
-----------------------
/**
* Authentication provider for a HttpConduit.
* Each authentication provider supports one rfc2617 authentication
* mechanism.
*
* http://www.ietf.org/rfc/rfc2617.txt
*/
public interface HttpClientAuthenticationProvider {
void setCredentialsProvider(CredentialsProvider credentialsProvider);
/**
*
* @return authentication mechanism name supported by this
provider. May not return null
*/
String getMechanismName();
/**
* Processes the authentication token and returns the token
* to be sent to the counterpart
*
* @param url where we connect to
* @param requestMethod http request method that is used to access
the url
* @param token from WWW-Authenticate header
* @return token to be sent to counterpart for next try or null if
authentication is finished
*/
String processChallenge(URL url, String requestMethod, String token);
}
------------------------
public interface CredentialsProvider {
/**
*
* @param url
* @param realm
* @return user name and password for the given realm or null if
none found
*/
UserAndPassword getCredentialsForUrlAndRealm(URL url, String realm);
}
--
----
http://www.liquid-reality.de