Skip to content

Commit

Permalink
Integrate vert.x routes with security
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Mar 19, 2020
1 parent 895da87 commit e7e4386
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
import org.jboss.logging.Logger;

import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.quarkus.runtime.TemplateHtmlBuilder;
import io.quarkus.security.ForbiddenException;
import io.quarkus.security.UnauthorizedException;
import io.quarkus.vertx.http.runtime.security.HttpAuthenticator;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;

Expand Down Expand Up @@ -40,6 +44,25 @@ public void handle(RoutingContext event) {
event.response().end();
return;
}
//this can happen if there is no auth mechanisms
if (event.failure() instanceof UnauthorizedException) {
HttpAuthenticator authenticator = event.get(HttpAuthenticator.class.getName());
if (authenticator != null) {
authenticator.sendChallenge(event, new Runnable() {
@Override
public void run() {
event.response().end();
}
});
} else {
event.response().setStatusCode(HttpResponseStatus.UNAUTHORIZED.code()).end();
}
return;
}
if (event.failure() instanceof ForbiddenException) {
event.response().setStatusCode(HttpResponseStatus.FORBIDDEN.code()).end();
return;
}
event.response().setStatusCode(500);
String uuid = BASE_ID + ERROR_COUNT.incrementAndGet();
String details = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import io.quarkus.vertx.http.runtime.filters.GracefulShutdownFilter;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Future;
import io.vertx.core.Handler;
Expand All @@ -66,6 +67,7 @@
import io.vertx.core.net.PemKeyCertOptions;
import io.vertx.core.net.PfxOptions;
import io.vertx.core.net.SocketAddress;
import io.vertx.core.net.impl.ConnectionBase;
import io.vertx.core.net.impl.VertxHandler;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;
Expand Down Expand Up @@ -874,8 +876,27 @@ public Handler<RoutingContext> createBodyHandler(HttpConfiguration httpConfigura
return new Handler<RoutingContext>() {
@Override
public void handle(RoutingContext event) {
event.request().resume();
bodyHandler.handle(event);
if (!Context.isOnEventLoopThread()) {
((ConnectionBase) event.request().connection()).channel().eventLoop().execute(new Runnable() {
@Override
public void run() {
try {
//this can happen if blocking authentication is involved for get requests
if (!event.request().isEnded()) {
event.request().resume();
bodyHandler.handle(event);
} else {
event.next();
}
} catch (Throwable t) {
event.fail(t);
}
}
});
} else {
event.request().resume();
bodyHandler.handle(event);
}
}
};
}
Expand Down
10 changes: 10 additions & 0 deletions extensions/vertx-web/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@
<artifactId>quarkus-vertx-web</artifactId>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-security</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elytron-security-properties-file-deployment</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.security.RolesAllowed;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
Expand All @@ -30,8 +31,12 @@ public class SimpleRouteTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(SimpleBean.class,
SimpleEventBusBean.class, SimpleRoutesBean.class, Transformer.class));
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addAsResource("application.properties")
.addAsResource("test-users.properties")
.addAsResource("test-roles.properties")
.addClasses(SimpleBean.class,
SimpleEventBusBean.class, SimpleRoutesBean.class, Transformer.class));

@Test
public void testSimpleRoute() {
Expand All @@ -51,6 +56,13 @@ public void testSimpleRoute() {
when().get("/request").then().statusCode(200).body(is("HellO!"));
}

@Test
public void testSecuredRoute() {
when().get("/secured").then().statusCode(401);
given().auth().basic("bob", "bob").get("/secured").then().statusCode(403);
given().auth().basic("alice", "alice").get("/secured").then().statusCode(200);
}

static class SimpleBean {

@Inject
Expand All @@ -64,6 +76,12 @@ void hello(RoutingContext context) {
context.response().setStatusCode(200).end("Hello " + (name != null ? name : "world") + "!");
}

@Route(path = "/secured")
@RolesAllowed("admin") //we are just testing that this is actually denied
void secure(RoutingContext context) {
context.response().setStatusCode(200).end();
}

@Route(path = "/rx-hello")
void rxHello(io.vertx.reactivex.ext.web.RoutingContext context) {
String name = context.request().getParam("name");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
quarkus.security.users.file.enabled=true
quarkus.security.users.file.users=test-users.properties
quarkus.security.users.file.roles=test-roles.properties
quarkus.security.users.file.plain-text=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bob=user
alice=admin
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bob=bob
alice=alice
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package io.quarkus.vertx.web.runtime;

import io.quarkus.arc.Arc;
import io.quarkus.arc.ManagedContext;
import io.quarkus.arc.runtime.BeanInvoker;
import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser;
import io.quarkus.vertx.web.Route;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
Expand All @@ -14,7 +17,24 @@ public interface RouteHandler extends Handler<RoutingContext>, BeanInvoker<Routi

@Override
default void handle(RoutingContext context) {
BeanInvoker.super.invoke(context);
QuarkusHttpUser user = (QuarkusHttpUser) context.user();
ManagedContext requestContext = Arc.container().requestContext();
if (requestContext.isActive()) {
if (user != null) {
Arc.container().beanManager().fireEvent(user.getSecurityIdentity());
}
invokeBean(context);
} else {
try {
requestContext.activate();
if (user != null) {
Arc.container().beanManager().fireEvent(user.getSecurityIdentity());
}
invokeBean(context);
} finally {
requestContext.terminate();
}
}
}

}

0 comments on commit e7e4386

Please sign in to comment.