Skip to content

Commit

Permalink
Merge pull request #24226 from knutwannheden/23254
Browse files Browse the repository at this point in the history
Add config quarkus.security.auth.enabled-in-dev-mode
  • Loading branch information
sberyozkin authored Mar 16, 2022
2 parents 5d31bc5 + b1f0ca0 commit 9b9623c
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 3 deletions.
9 changes: 8 additions & 1 deletion docs/src/main/asciidoc/security-customization.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ public class SecurityOverrideFilter implements ContainerRequestFilter {

== Disabling Authorization

If you have a good reason to disable the authorization (for example, when testing) then you can register a custom `AuthorizationController`:
If you have a good reason to disable the authorization then you can register a custom `AuthorizationController`:

[source,java]
----
Expand All @@ -299,6 +299,13 @@ public class DisabledAuthController extends AuthorizationController {
}
----

For manual testing Quarkus provides a convenient config property to disable authorization in dev mode. This property has the exact same effect as the custom `AuthorizationController` shown above, but is only available in dev mode:

[source,properties]
----
quarkus.security.auth.enabled-in-dev-mode=false
----

Please also see xref:security-testing.adoc#testing-security[TestingSecurity Annotation] section on how to disable the security checks using `TestSecurity` annotation.

== Registering Security Providers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
public final class SecurityConfig {

/**
* Whether authorization is enabled in dev mode or not. In other launch modes authorization is always enabled.
*/
@ConfigItem(name = "auth.enabled-in-dev-mode", defaultValue = "true")
public boolean authorizationEnabledInDevMode;

/**
* List of security providers to enable for reflection
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import io.quarkus.deployment.builditem.ApplicationClassPredicateBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.GeneratedNativeImageClassBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.nativeimage.JPMSExportBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
Expand All @@ -57,6 +58,7 @@
import io.quarkus.gizmo.MethodDescriptor;
import io.quarkus.gizmo.ResultHandle;
import io.quarkus.gizmo.TryBlock;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.security.runtime.IdentityProviderManagerCreator;
import io.quarkus.security.runtime.SecurityBuildTimeConfig;
Expand All @@ -75,6 +77,7 @@
import io.quarkus.security.runtime.interceptor.SecurityHandler;
import io.quarkus.security.spi.AdditionalSecuredClassesBuildItem;
import io.quarkus.security.spi.runtime.AuthorizationController;
import io.quarkus.security.spi.runtime.DevModeDisabledAuthorizationController;
import io.quarkus.security.spi.runtime.SecurityCheck;
import io.quarkus.security.spi.runtime.SecurityCheckStorage;

Expand Down Expand Up @@ -590,8 +593,12 @@ void registerAdditionalBeans(BuildProducer<AdditionalBeanBuildItem> beans) {
}

@BuildStep
AdditionalBeanBuildItem authorizationController() {
return AdditionalBeanBuildItem.builder().addBeanClass(AuthorizationController.class).build();
AdditionalBeanBuildItem authorizationController(LaunchModeBuildItem launchMode) {
Class<? extends AuthorizationController> controllerClass = AuthorizationController.class;
if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT && !security.authorizationEnabledInDevMode) {
controllerClass = DevModeDisabledAuthorizationController.class;
}
return AdditionalBeanBuildItem.builder().addBeanClass(controllerClass).build();
}

static class AdditionalSecured {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.security.spi.runtime;

import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.inject.Singleton;
import javax.interceptor.Interceptor;

import io.quarkus.runtime.LaunchMode;

/**
* Controller used in dev mode if {@code quarkus.security.auth.enabled-in-dev-mode=false}.
*/
@Alternative
@Priority(Interceptor.Priority.LIBRARY_AFTER)
@Singleton
public final class DevModeDisabledAuthorizationController extends AuthorizationController {

public boolean isAuthorizationEnabled() {
if (LaunchMode.current() != LaunchMode.DEVELOPMENT) {
throw new IllegalStateException("This implementation is only available in dev mode");
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.quarkus.test.security;

import static org.hamcrest.CoreMatchers.equalTo;

import javax.annotation.security.DenyAll;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

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

import io.quarkus.test.QuarkusDevModeTest;
import io.restassured.RestAssured;

public class DisabledAuthorizationTest {
@RegisterExtension
static final QuarkusDevModeTest test = new QuarkusDevModeTest()
.withApplicationRoot((jar) -> jar
.addClasses(HelloResource.class)
.add(new StringAsset("quarkus.security.auth.enabled-in-dev-mode=false"), "application.properties"));

@Test
void verifyAuthorizationEnablement() {
RestAssured.given()
.when().get("/")
.then()
.statusCode(200)
.body(equalTo("hello"));
}

@ApplicationScoped
@Path("/")
@DenyAll
public static class HelloResource {
@GET
public String hello() {
return "hello";
}
}
}

0 comments on commit 9b9623c

Please sign in to comment.