Skip to content

Commit

Permalink
RESTEasy classic servlets - add RoutingContext to active request context
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik committed Jan 28, 2023
1 parent 24bae58 commit 963e373
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import io.quarkus.security.identity.CurrentIdentityAssociation;

/**
* @author Michal Szynkiewicz, michal.l.szynkiewicz@gmail.com
*/
@Path("/roles")
@PermitAll
public class RolesAllowedResource {

@Inject
CurrentIdentityAssociation currentIdentityAssociation;

@GET
@RolesAllowed({ "user", "admin" })
public String defaultSecurity() {
Expand All @@ -24,4 +31,10 @@ public String admin() {
return "admin";
}

@Path("/admin/security-identity")
@RolesAllowed("admin")
@GET
public String getSecurityIdentity() {
return currentIdentityAssociation.getIdentity().getPrincipal().getName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package io.quarkus.resteasy.test.security;

import java.util.List;
import java.util.function.Supplier;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.control.ActivateRequestContext;

import org.hamcrest.Matchers;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.builder.Version;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.SecurityIdentityAugmentor;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.quarkus.security.test.utils.TestIdentityController;
import io.quarkus.security.test.utils.TestIdentityProvider;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import io.smallrye.mutiny.Uni;

public class SecurityIdentityAugmentorTest {

@RegisterExtension
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addAsResource(new StringAsset("quarkus.http.auth.basic=true\n"), "application.properties")
.addClasses(TestIdentityProvider.class, RolesAllowedResource.class, TestIdentityController.class))
.setForcedDependencies(List.of(Dependency.of("io.quarkus", "quarkus-undertow", Version.getVersion())));

@BeforeAll
public static void setupUsers() {
TestIdentityController.resetRoles().add("admin", "admin");
}

@Test
public void testSecurityIdentityAugmentor() {
RestAssured.given().auth().basic("admin", "admin").get("/roles/admin/security-identity").then().statusCode(200)
.body(Matchers.is("admin"));
}

@ApplicationScoped
public static class CustomAugmentor implements SecurityIdentityAugmentor {

@Override
public Uni<SecurityIdentity> augment(SecurityIdentity identity, AuthenticationRequestContext context) {
if (identity.isAnonymous()) {
return Uni.createFrom().item(identity);
}
return context.runBlocking(build(identity));
}

@ActivateRequestContext
Supplier<SecurityIdentity> build(SecurityIdentity identity) {
QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder(identity);
builder.addRole("admin");
return builder::build;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,15 @@ public T call(HttpServerExchange exchange, C context) throws Exception {
// Not sure what to do here
ManagedContext requestContext = beanContainer.requestContext();
if (requestContext.isActive()) {
if (currentVertxRequest.getCurrent() == null && exchange != null
&& exchange.getDelegate() instanceof VertxHttpExchange) {
// goal here is to add event to the Vert.X request when Smallrye Context Propagation
// creates fresh instance of request context without the event; we experienced
// the request context activated and terminated by ActivateRequestContextInterceptor
// invoked for the SecurityIdentityAugmentor that was (re)created during permission checks
addEventToVertxRequest(exchange);
}

return action.call(exchange, context);
} else if (exchange == null) {
requestContext.activate();
Expand All @@ -578,9 +587,7 @@ public T call(HttpServerExchange exchange, C context) throws Exception {
try {
requestContext.activate(existingRequestContext);

VertxHttpExchange delegate = (VertxHttpExchange) exchange.getDelegate();
RoutingContext rc = (RoutingContext) delegate.getContext();
currentVertxRequest.setCurrent(rc);
RoutingContext rc = addEventToVertxRequest(exchange);

if (association != null) {
QuarkusHttpUser existing = (QuarkusHttpUser) rc.user();
Expand Down Expand Up @@ -631,6 +638,13 @@ public void onStartAsync(AsyncEvent event) throws IOException {
}
}
}

private RoutingContext addEventToVertxRequest(HttpServerExchange exchange) {
VertxHttpExchange delegate = (VertxHttpExchange) exchange.getDelegate();
RoutingContext rc = (RoutingContext) delegate.getContext();
currentVertxRequest.setCurrent(rc);
return rc;
}
};
}
});
Expand Down

0 comments on commit 963e373

Please sign in to comment.