Hi,
The Jersey client using the Apache HTTP client is now in the repo:
http://download.java.net/maven/2/com/sun/jersey/contribs/jersey-apache-client/1.0.2-SNAPSHOT/
I need to improve on the JavaDoc.
Below is a unit test for authentication that should give you an idea
on how to use it.
Paul.
package com.sun.jersey.client.apache.impl;
import javax.ws.rs.Path;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.container.filter.LoggingFilter;
import com.sun.jersey.api.core.DefaultResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.client.apache.ApacheHttpClient;
import com.sun.jersey.client.apache.config.ApacheHttpClientConfig;
import
com.sun.jersey.client.apache.config.DefaultApacheHttpClientConfig;
import com.sun.jersey.spi.resource.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScheme;
import
org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
import org.apache.commons.httpclient.auth.CredentialsProvider;
/**
*
* @author Paul.Sandoz_at_Sun.Com
*/
public class AuthTest extends AbstractGrizzlyServerTester {
public AuthTest(String testName) {
super(testName);
}
@Path("/")
public static class PreemptiveAuthResource {
@GET
public String get(@Context HttpHeaders h) {
String value =
h.getRequestHeaders().getFirst("Authorization");
assertNotNull(value);
return "GET";
}
}
public void testPreemptiveAuth() {
ResourceConfig rc = new
DefaultResourceConfig(PreemptiveAuthResource.class);
rc
.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS,
LoggingFilter.class.getName());
startServer(rc);
DefaultApacheHttpClientConfig config = new
DefaultApacheHttpClientConfig();
config.getState().setCredentials(null, null, -1, "name",
"password");
config
.getProperties
().put(ApacheHttpClientConfig.PROPERTY_PREEMPTIVE_AUTHENTICATION, true);
ApacheHttpClient c = ApacheHttpClient.create(config);
WebResource r = c.resource(getUri().build());
assertEquals("GET", r.get(String.class));
}
@Path("/test")
@Singleton
public static class AuthResource {
int requestCount = 0;
@GET
public String get(@Context HttpHeaders h) {
requestCount++;
String value =
h.getRequestHeaders().getFirst("Authorization");
if (value == null) {
assertEquals(1, requestCount);
throw new
WebApplicationException(Response.status(401).header("WWW-
Authenticate", "Basic realm=\"WallyWorld\"").build());
} else {
assertTrue(requestCount > 1);
}
return "GET";
}
}
public void testAuth() {
ResourceConfig rc = new
DefaultResourceConfig(AuthResource.class);
rc
.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS,
LoggingFilter.class.getName());
startServer(rc);
DefaultApacheHttpClientConfig config = new
DefaultApacheHttpClientConfig();
config.getState().setCredentials(null, null, -1, "name",
"password");
ApacheHttpClient c = ApacheHttpClient.create(config);
WebResource r = c.resource(getUri().path("test").build());
assertEquals("GET", r.get(String.class));
}
static class BasicCredentialsProvider implements
CredentialsProvider {
private boolean called;
public Credentials getCredentials(AuthScheme arg0, String
arg1, int arg2, boolean arg3) throws CredentialsNotAvailableException {
called = true;
return new UsernamePasswordCredentials ("name",
"password");
}
boolean isCalled() {
return called;
}
}
public void testAuthInteractive() {
ResourceConfig rc = new
DefaultResourceConfig(AuthResource.class);
rc
.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS,
LoggingFilter.class.getName());
startServer(rc);
DefaultApacheHttpClientConfig config = new
DefaultApacheHttpClientConfig();
config
.getProperties().put(ApacheHttpClientConfig.PROPERTY_INTERACTIVE, true);
BasicCredentialsProvider bcp = new BasicCredentialsProvider();
config
.getProperties
().put(ApacheHttpClientConfig.PROPERTY_CREDENTIALS_PROVIDER, bcp);
ApacheHttpClient c = ApacheHttpClient.create(config);
WebResource r = c.resource(getUri().path("test").build());
assertEquals("GET", r.get(String.class));
assertTrue(bcp.isCalled());
}
}
On Jan 28, 2009, at 6:51 PM, Matthieu Riou wrote:
> On Wed, Jan 28, 2009 at 9:16 AM, Steve Sims <steve_at_steveandgeorge.co.uk
> > wrote:
> Hi Matthieu,
>
> I originally used java.net.Authenticator.setDefault() but had
> problems setting it to null after each test (as in it would continue
> to send the same credentials). The other way to do it, as detailed
> in the thread that you mention, is to add a filter to the Jersey
> client which will create the HTTP Authorization header in the
> outgoing message which is required for Basic authentication.
>
> The following code snippet requires the Apache Commons Digest
> library to do the Base64 encoding:
>
> class BasicAuthenticationFilter extends ClientFilter {
>
> private String username;
> private String password;
>
> public BasicAuthenticationFilter(String username, String password) {
> this.username = username;
> this.password = password;
> }
>
> @Override
> public ClientResponse handle(ClientRequest cr) throws
> ClientHandlerException {
> if (null != username && null != password) {
> byte[] unencoded = (username + ":" +
> password).getBytes(Charset.forName("UTF-8"));
> byte[] cred = new Base64().encode(unencoded);
> String credString = new String(cred);
> String authHeader = "Basic " + credString;
> cr.getMetadata().add("authorization", authHeader);
> }
> // Call the next client handler in the filter chain
> return this.getNext().handle(cr);
> }
> }
>
> and then you just add it to the client like so:
>
> Client client = Client.create();
> ClientFilter authFilter = new BasicAuthenticationFilter("userid",
> "password);
> client.addFilter(authFilter);
>
> There's a minor issue (#196) which was fixed today in the trunk
> (thanks Paul!) which means that client.removeFilter(authFilter) will
> throw an exception, but then I'm only removing the filter because in
> some tests I wanted to change the credentials. I just worked around
> it by calling client.removeAllFilters() because that was the only
> filter I had attached.
>
> Obviously the above filter is pretty rough and won't do everything
> such as only sending the credentials when requested by the server
> etc. but it's something else that may fit the bill if
> Authenticator.setDefault() doesn't quite work.
>
> Thanks Steve, much appreciated. I think I'll still try to build a
> client from the current SVN content but if I can't make it work I'll
> fall back to your approach.
>
> Cheers,
> Matthieu
>
>
> Hope this helps,
>
> Steve
>
>
> Paul Sandoz wrote:
>
> On Jan 28, 2009, at 5:22 PM, Matthieu Riou wrote:
>
> Hi,
>
> I was wondering what were the options to do Basic Auth with the
> Jersey client in 1.0.1. I've seen an e-mail thread dating back from
> November where a patch had been proposed but it doesn't seem it's
> been integrated in 1.0.1 or maybe in a different form. I've been
> staring at the Javadoc for quite some time but couldn't find
> anything that looked like auth methods.
>
>
> Currently the only way is to use the java.net.Authenticator [1]
> because by default HttpURLConnection is utilized. Which is not ideal
> because it is a static, per JVM, configuration.
>
> We are working on support using the Apache HTTP client where basic
> auth can be set up on a per client basis. I hope this can make the
> 1.0.2 release, i just need to work on the implementation to ensure
> it is thread safe.
>
> Paul.
>
> [1] http://java.sun.com/javase/6/docs/technotes/guides/net/http-auth.html
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>