Hi Adrian, Thank you for your detailed answer. I'd just like to check that I've understood okay, and ask one more favour (!):
1./ I can't determine what type of credentials I should use directly with the HttpClient API. I need to look at HTTP response headers and determine that myself. This leads onto another question... what headers are returned by an NTLM-protected server to indicate that I need to authenticate with NTLM -- so that I know what to "sniff" for, and what response does it xpect -- out of interest (I'd like a short example)? 2./ I should be using one instance of HttpClient per connected user, so that I can reflect correctly the credentials for the end user (stored in the state of the HttpClient). In practice, I could store one instance of HttpClient in the session attributes of the servlet context for the webapp of the highlighting service. 3./ thanks for the example. it does help! Sorry to ask such questions. I don't have an NTLM test environment, so it's fun trying to develop support for it..!! Thanks for the help so far anyway! - Chris PS: re: the "limitation"... pester, pester, I'd be happy if it were fixed! :) ----- Original Message ----- From: "Adrian Sutton" <[EMAIL PROTECTED]> To: "'Commons HttpClient Project'" <[EMAIL PROTECTED]> Sent: Thursday, February 27, 2003 1:00 AM Subject: RE: Using httpclient on the server to intercept and modify HTTP response > Hi Chris, > HttpClient should be able to do everything you need it to, but you have hit > on one limitation that I've been meaning to fix for a long time now. > There's ways around it and if you pester me enough I might finally get > around to implementing it properly. :) More below. > > >1./ when connecting to something with the HTTPClient API, how do I > determine > >dynamically which type of credentials I should use, if any? > > You can always use NTCredentials as they extend UsernamePasswordCredentials, > this is the approach I take. There is a definitely limitation in HttpClient > that it doesn't tell you what credentials it needs. This is part 1 of the > stuff I've been meaning to do. It should give you the Class for the > credentials type and there should be some way of knowing what parameters it > needs as well. > > >2./ given that I'm forwarding requests from many clients via one host, are > >there any problems or pitfalls with multiple connections from that host > >using different credentials for each client? is there any caching for > >example that might mean that the first NT login is used for some/all > >subsequent requests that should in fact be using the credentials for a > >different client? > > That depends. Credentials are stored per realm and are cached in the > HttpState instance for each HttpClient. For NTLM, the domain name of the > server is used as the realm. So if you have two users with different > credentials who attempt to access the same NTLM server, the credentials will > get mixed up. You can (and should) however create a separate HttpState for > each client so that the credentials don't get mixed up too much and this > will also prevent cookies getting mixed up and a bunch of other stuff. > > Laura has requested a version of executeMethod() in HttpClient that accepts > a specific state to use and that definitely seems like a good idea - > currently she is using the HttpMethod's directly and not using the > HttpClient class itself. We'd like everyone to use the HttpClient class as > it makes development easier so I'm hoping that someone (possibly myself) > will look into the possibility of implementing that for 2.0. It depends on > how complex it is though. > > >3./ as I'll need to ask the client to provide credentials, I can either use > >a form or a BASIC authentification request. If I limit the request to > >"username" and "password" fields, can I safely request that the client's > >username contains "DOMAIN\username" (and then decode it), as I'm not clear > >about where I should obtain domain names for? > > You could take that approach, or you could use the nasty hack below to > detect if you're authenticating to NTLM or not and add a specific domain > field to your auth dialog/form. > > The nasty hack to find out the realm to authenticate against and whether or > not you need a domain involves: > ..... > // If you might have to authenticate with proxies, don't forget to > check the > // Proxy-Authenticate header as well. > String realm = get.getResponseHeader("WWW-Authenticate").getValue(); > boolean isNTLM = (realm != null && > realm.toLowerCase().indexOf("ntlm") >= 0); > String tmpRealm; > if (isNTLM) { > if (proxy) { > tmpRealm = client.getProxyHost(); > } else { > tmpRealm = src.getHost(); > } > } else { > tmpRealm = parseRealmFromChallenge(realm); > } > // isNTLM now stores whether or not you need to get a domain from > the user as well. > // tmpRealm now contains the name of the realm you're > authenticating against. > .... > > > // Blantantly ripped from HttpClient's Authenticator.java You may want > to check for updates. > private String parseRealmFromChallenge(String challenge) { > log.trace("enter parseRealmFromChallenge(String challenge)"); > try { > StringTokenizer strtok = new StringTokenizer(challenge, "="); > String realm = strtok.nextToken().trim(); > int firstq = realm.indexOf('"'); > int lastq = realm.lastIndexOf('"'); > > if ((firstq + 1) < lastq) { > realm = realm.substring(firstq + 1, lastq); > } > > return realm; > } catch (Exception ex) { > System.err.println("Failed to parse realm: " + challenge + " - " > + ex.getMessage()); > return null; > } > } > > Hope that helps.... > > Adrian Sutton, Software Engineer > Ephox Corporation > www.ephox.com > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]