diff --git a/extensions/smallrye-graphql/deployment/pom.xml b/extensions/smallrye-graphql/deployment/pom.xml
index d7ab02dae4e573..71233a947fce99 100644
--- a/extensions/smallrye-graphql/deployment/pom.xml
+++ b/extensions/smallrye-graphql/deployment/pom.xml
@@ -70,6 +70,16 @@
quarkus-smallrye-opentracing
test
+
+ io.quarkus
+ quarkus-elytron-security
+ test
+
+
+ io.quarkus
+ quarkus-elytron-security-properties-file
+ test
+
diff --git a/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java b/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java
index 6f0295b4c26863..87ca9733ca63b9 100644
--- a/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java
+++ b/extensions/smallrye-graphql/deployment/src/main/java/io/quarkus/smallrye/graphql/deployment/SmallRyeGraphQLProcessor.java
@@ -191,7 +191,8 @@ void buildEndpoints(
BuildProducer notFoundPageDisplayableEndpointProducer,
LaunchModeBuildItem launchMode,
SmallRyeGraphQLRecorder recorder,
- ShutdownContextBuildItem shutdownContext) throws IOException {
+ ShutdownContextBuildItem shutdownContext,
+ BeanContainerBuildItem beanContainerBuildItem) {
/*
* Ugly Hack
@@ -215,7 +216,7 @@ void buildEndpoints(
Boolean allowGet = ConfigProvider.getConfig().getOptionalValue(ConfigKey.ALLOW_GET, boolean.class).orElse(false);
- Handler executionHandler = recorder.executionHandler(allowGet);
+ Handler executionHandler = recorder.executionHandler(allowGet, beanContainerBuildItem.getValue());
routeProducer.produce(new RouteBuildItem(quarkusConfig.rootPath, executionHandler, HandlerType.BLOCKING));
Handler schemaHandler = recorder.schemaHandler();
diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/SecurityTest.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/SecurityTest.java
new file mode 100644
index 00000000000000..d156ab94a277d5
--- /dev/null
+++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/SecurityTest.java
@@ -0,0 +1,79 @@
+package io.quarkus.smallrye.graphql.deployment;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+import javax.annotation.security.RolesAllowed;
+import javax.enterprise.context.ApplicationScoped;
+
+import org.eclipse.microprofile.graphql.GraphQLApi;
+import org.eclipse.microprofile.graphql.Query;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.quarkus.test.QuarkusUnitTest;
+import io.restassured.RestAssured;
+import io.restassured.http.Header;
+
+public class SecurityTest extends AbstractGraphQLTest {
+
+ @RegisterExtension
+ static QuarkusUnitTest test = new QuarkusUnitTest()
+ .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
+ .addClass(SecuredApi.class)
+ .addAsResource("application-secured.properties", "application.properties")
+ .addAsResource("users.properties")
+ .addAsResource("roles.properties")
+ .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"));
+
+ @Test
+ public void testAuthenticatedUser() {
+ String query = getPayload("{ foo }");
+ RestAssured.given()
+ .header(new Header("Authorization", "Basic ZGF2aWQ6cXdlcnR5MTIz"))
+ .body(query)
+ .contentType(MEDIATYPE_JSON)
+ .post("/graphql/")
+ .then()
+ .assertThat()
+ .body("errors", nullValue())
+ .body("data.foo", equalTo("foo"));
+ }
+
+ @Test
+ public void testUnauthorizedRole() {
+ String query = getPayload("{ bar }");
+ RestAssured.given()
+ .header(new Header("Authorization", "Basic ZGF2aWQ6cXdlcnR5MTIz"))
+ .body(query)
+ .contentType(MEDIATYPE_JSON)
+ .post("/graphql")
+ .then()
+ .assertThat()
+ .body("errors", notNullValue())
+ .body("data.bar", nullValue());
+ }
+
+ @GraphQLApi
+ @ApplicationScoped
+ public static class SecuredApi {
+
+ @Query
+ @RolesAllowed("fooRole")
+ public String foo() {
+ return "foo";
+ }
+
+ @Query
+ @RolesAllowed("barRole")
+ public String bar() {
+ return "bar";
+ }
+
+ }
+
+}
diff --git a/extensions/smallrye-graphql/deployment/src/test/resources/application-secured.properties b/extensions/smallrye-graphql/deployment/src/test/resources/application-secured.properties
new file mode 100644
index 00000000000000..dbe0d0ba62978d
--- /dev/null
+++ b/extensions/smallrye-graphql/deployment/src/test/resources/application-secured.properties
@@ -0,0 +1,5 @@
+quarkus.security.users.file.enabled=true
+quarkus.security.users.file.plain-text=true
+quarkus.security.users.file.users=users.properties
+quarkus.security.users.file.roles=roles.properties
+quarkus.http.auth.basic=true
\ No newline at end of file
diff --git a/extensions/smallrye-graphql/deployment/src/test/resources/roles.properties b/extensions/smallrye-graphql/deployment/src/test/resources/roles.properties
new file mode 100644
index 00000000000000..ef2a67ac7e9e64
--- /dev/null
+++ b/extensions/smallrye-graphql/deployment/src/test/resources/roles.properties
@@ -0,0 +1 @@
+david=fooRole
\ No newline at end of file
diff --git a/extensions/smallrye-graphql/deployment/src/test/resources/users.properties b/extensions/smallrye-graphql/deployment/src/test/resources/users.properties
new file mode 100644
index 00000000000000..0f1cc7592d0553
--- /dev/null
+++ b/extensions/smallrye-graphql/deployment/src/test/resources/users.properties
@@ -0,0 +1 @@
+david=qwerty123
\ No newline at end of file
diff --git a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java
index 558944a56205d9..9343d1fc4beb0f 100644
--- a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java
+++ b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLExecutionHandler.java
@@ -13,6 +13,8 @@
import io.quarkus.arc.Arc;
import io.quarkus.arc.ManagedContext;
+import io.quarkus.security.identity.CurrentIdentityAssociation;
+import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser;
import io.smallrye.graphql.execution.ExecutionService;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
@@ -29,9 +31,11 @@ public class SmallRyeGraphQLExecutionHandler implements Handler
private static final String QUERY = "query";
private static final String OK = "OK";
private volatile ExecutionService executionService;
+ private final CurrentIdentityAssociation currentIdentityAssociation;
- public SmallRyeGraphQLExecutionHandler(boolean allowGet) {
+ public SmallRyeGraphQLExecutionHandler(boolean allowGet, CurrentIdentityAssociation currentIdentityAssociation) {
this.allowGet = allowGet;
+ this.currentIdentityAssociation = currentIdentityAssociation;
}
@Override
@@ -50,6 +54,10 @@ public void handle(final RoutingContext ctx) {
}
private void doHandle(final RoutingContext ctx) {
+ if (currentIdentityAssociation != null) {
+ currentIdentityAssociation.setIdentity(QuarkusHttpUser.getSecurityIdentity(ctx, null));
+ }
+
HttpServerRequest request = ctx.request();
HttpServerResponse response = ctx.response();
diff --git a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java
index 4924ad20bb02fb..e5c59848fe307f 100644
--- a/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java
+++ b/extensions/smallrye-graphql/runtime/src/main/java/io/quarkus/smallrye/graphql/runtime/SmallRyeGraphQLRecorder.java
@@ -5,6 +5,7 @@
import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
+import io.quarkus.security.identity.CurrentIdentityAssociation;
import io.quarkus.smallrye.graphql.runtime.spi.QuarkusClassloadingService;
import io.quarkus.vertx.http.runtime.ThreadLocalHandler;
import io.smallrye.graphql.cdi.producer.GraphQLProducer;
@@ -23,8 +24,8 @@ public void createExecutionService(BeanContainer beanContainer, Schema schema) {
graphQLProducer.initialize();
}
- public Handler executionHandler(boolean allowGet) {
- return new SmallRyeGraphQLExecutionHandler(allowGet);
+ public Handler executionHandler(boolean allowGet, BeanContainer beanContainer) {
+ return new SmallRyeGraphQLExecutionHandler(allowGet, beanContainer.instance(CurrentIdentityAssociation.class));
}
public Handler schemaHandler() {