package org.jboss.resteasy.test.security;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import org.jboss.resteasy.client.jaxrs.ClientHttpEngine;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.plugins.server.embedded.SimpleSecurityDomain;
import org.jboss.resteasy.plugins.server.sun.http.HttpServerContainer;
import org.jboss.resteasy.test.TestPortProvider;
import org.jboss.resteasy.util.HttpResponseCodes;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.annotation.security.DenyAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import java.util.List;
import static org.jboss.resteasy.test.TestPortProvider.createProxy;
import static org.jboss.resteasy.test.TestPortProvider.generateURL;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class BasicAuthTest
{
private static Dispatcher dispatcher;
@Path("/secured")
public static interface BaseProxy
{
@GET
String get();
@GET
@Path("/authorized")
String getAuthorized();
@GET
@Path("/deny")
String deny();
@GET
@Path("/failure")
List<String> getFailure();
}
@Path("/secured")
public static class BaseResource
{
@GET
@Path("/failure")
@RolesAllowed("admin")
public List<String> getFailure()
{
return null;
}
@GET
public String get(@Context SecurityContext ctx)
{
System.out.println("********* IN SECURE CLIENT");
if (!ctx.isUserInRole("admin"))
{
System.out.println("NOT IN ROLE!!!!");
throw new WebApplicationException(403);
}
return "hello";
}
@GET
@Path("/authorized")
@RolesAllowed("admin")
public String getAuthorized()
{
return "authorized";
}
@GET
@Path("/deny")
@DenyAll
public String deny()
{
return "SHOULD NOT BE REACHED";
}
}
@Path("/secured2")
public static class BaseResource2
{
public String get(@Context SecurityContext ctx)
{
System.out.println("********* IN SECURE CLIENT");
if (!ctx.isUserInRole("admin"))
{
System.out.println("NOT IN ROLE!!!!");
throw new WebApplicationException(403);
}
return "hello";
}
@GET
@Path("/authorized")
@RolesAllowed("admin")
public String getAuthorized()
{
return "authorized";
}
}
@BeforeClass
public static void before() throws Exception
{
SimpleSecurityDomain domain = new SimpleSecurityDomain();
String[] roles =
{"admin"};
String[] basic =
{"user"};
domain.addUser("bill", "password", roles);
domain.addUser("mo", "password", basic);
dispatcher = HttpServerContainer.start("", domain).getDispatcher();
dispatcher.getRegistry().addPerRequestResource(BaseResource.class);
dispatcher.getRegistry().addPerRequestResource(BaseResource2.class);
}
@AfterClass
public static void after() throws Exception
{
HttpServerContainer.stop();
}
@Test
public void testProxy() throws Exception
{
DefaultHttpClient httpClient = new DefaultHttpClient();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("bill", "password");
httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY), credentials);
ClientHttpEngine engine = createAuthenticatingEngine(httpClient);
Client client = new ResteasyClientBuilder().httpEngine(engine).build();
ResteasyWebTarget target = (ResteasyWebTarget) client.target(generateURL(""));
BaseProxy proxy = target.proxy(BaseProxy.class);
String val = proxy.get();
Assert.assertEquals(val, "hello");
val = proxy.getAuthorized();
Assert.assertEquals(val, "authorized");
}
@Test
public void testProxyFailure() throws Exception
{
BaseProxy proxy = createProxy(BaseProxy.class, TestPortProvider.generateBaseUrl());
try
{
proxy.getFailure();
}
catch (NotAuthorizedException e)
{
Assert.assertEquals(e.getResponse().getStatus(), 401);
e.getResponse().close();
}
}
@Test
public void testSecurity() throws Exception
{
DefaultHttpClient httpClient = new DefaultHttpClient();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("bill", "password");
httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY), credentials);
ClientHttpEngine engine = createAuthenticatingEngine(httpClient);
Client client = new ResteasyClientBuilder().httpEngine(engine).build();
{
Builder request = client.target(generateURL("/secured")).request();
Response response = request.get();
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals("hello", response.readEntity(String.class));
}
{
Builder request = client.target(generateURL("/secured/authorized")).request();
Response response = request.get();
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals("authorized", response.readEntity(String.class));
}
{
Builder request = client.target(generateURL("/secured/deny")).request();
Response response = request.get();
Assert.assertEquals(HttpResponseCodes.SC_FORBIDDEN, response.getStatus());
}
}
/**
* RESTEASY-579
*
* Found 579 bug when doing 575 so the test is here out of laziness
*
* @throws Exception
*/
@Test
public void test579() throws Exception
{
DefaultHttpClient httpClient = new DefaultHttpClient();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("bill", "password");
httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY), credentials);
ClientHttpEngine engine = createAuthenticatingEngine(httpClient);
Client client = new ResteasyClientBuilder().httpEngine(engine).build();
Response response = client.target(generateURL("/secured2")).request().get();
Assert.assertEquals(404, response.getStatus());
response.close();
}
@Test
public void testSecurityFailure() throws Exception
{
DefaultHttpClient httpClient = new DefaultHttpClient();
{
HttpGet method = new HttpGet(generateURL("/secured"));
HttpResponse response = httpClient.execute(method);
Assert.assertEquals(401, response.getStatusLine().getStatusCode());
EntityUtils.consume(response.getEntity());
}
ClientHttpEngine engine = createAuthenticatingEngine(httpClient);
Client client = new ResteasyClientBuilder().httpEngine(engine).build();
{
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("bill", "password");
httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY), credentials);
Response response = client.target(generateURL("/secured/authorized")).request().get();
Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus());
Assert.assertEquals("authorized", response.readEntity(String.class));
}
{
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("mo", "password");
httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY), credentials);
Response response = client.target(generateURL("/secured/authorized")).request().get();
Assert.assertEquals(HttpResponseCodes.SC_FORBIDDEN, response.getStatus());
response.close();
}
}
/**
* Create a ClientExecutor which does preemptive authentication.
*/
static private ClientHttpEngine createAuthenticatingEngine(DefaultHttpClient client)
{
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
HttpHost targetHost = new HttpHost("localhost", 8081);
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// Create ClientExecutor.
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(client, localContext);
return engine;
}
}