Skip to content

Commit

Permalink
Merge pull request #37022 from michalvavrik/feature/move-auth-basic-r…
Browse files Browse the repository at this point in the history
…ealm-to-runtime

Make basic realm and form authentication configuration properties only used during runtime the runtime properties
  • Loading branch information
sberyozkin authored Nov 12, 2023
2 parents 325746a + b08cf2f commit 80c11e9
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 184 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.vertx.http.deployment;

import static io.quarkus.arc.processor.DotNames.APPLICATION_SCOPED;
import static io.quarkus.arc.processor.DotNames.DEFAULT_BEAN;
import static io.quarkus.arc.processor.DotNames.SINGLETON;

import java.util.List;
Expand All @@ -11,12 +12,14 @@
import java.util.stream.Collectors;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Singleton;

import org.jboss.jandex.DotName;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.annotations.BuildProducer;
Expand All @@ -30,7 +33,6 @@
import io.quarkus.vertx.http.runtime.security.BasicAuthenticationMechanism;
import io.quarkus.vertx.http.runtime.security.EagerSecurityInterceptorStorage;
import io.quarkus.vertx.http.runtime.security.FormAuthenticationMechanism;
import io.quarkus.vertx.http.runtime.security.HttpAuthenticationMechanism;
import io.quarkus.vertx.http.runtime.security.HttpAuthenticator;
import io.quarkus.vertx.http.runtime.security.HttpAuthorizer;
import io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy;
Expand All @@ -43,6 +45,8 @@

public class HttpSecurityProcessor {

private static final DotName BASIC_AUTH_MECH_NAME = DotName.createSimple(BasicAuthenticationMechanism.class);

@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void produceNamedHttpSecurityPolicies(List<HttpSecurityPolicyBuildItem> httpSecurityPolicyBuildItems,
Expand Down Expand Up @@ -88,26 +92,23 @@ AdditionalBeanBuildItem initMtlsClientAuth(HttpBuildTimeConfig buildTimeConfig)
}

@BuildStep(onlyIf = IsApplicationBasicAuthRequired.class)
@Record(ExecutionTime.STATIC_INIT)
SyntheticBeanBuildItem initBasicAuth(
HttpSecurityRecorder recorder,
HttpBuildTimeConfig buildTimeConfig,
AdditionalBeanBuildItem initBasicAuth(HttpBuildTimeConfig buildTimeConfig,
BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformerProducer,
BuildProducer<SecurityInformationBuildItem> securityInformationProducer) {
SyntheticBeanBuildItem.ExtendedBeanConfigurator configurator = SyntheticBeanBuildItem
.configure(BasicAuthenticationMechanism.class)
.types(HttpAuthenticationMechanism.class)
.scope(Singleton.class)
.supplier(recorder.setupBasicAuth(buildTimeConfig));

if (!buildTimeConfig.auth.form.enabled && !isMtlsClientAuthenticationEnabled(buildTimeConfig)
&& !buildTimeConfig.auth.basic.orElse(false)) {
//if not explicitly enabled we make this a default bean, so it is the fallback if nothing else is defined
configurator.defaultBean();
annotationsTransformerProducer.produce(new AnnotationsTransformerBuildItem(AnnotationsTransformer
.appliedToClass()
.whenClass(cl -> BASIC_AUTH_MECH_NAME.equals(cl.name()))
.thenTransform(t -> t.add(DEFAULT_BEAN))));
if (buildTimeConfig.auth.basic.isPresent() && buildTimeConfig.auth.basic.get()) {
securityInformationProducer.produce(SecurityInformationBuildItem.BASIC());
}
}

return configurator.done();
return AdditionalBeanBuildItem.builder().setUnremovable().addBeanClass(BasicAuthenticationMechanism.class).build();
}

public static boolean applicationBasicAuthRequired(HttpBuildTimeConfig buildTimeConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ public class AuthConfig {
@ConfigItem
public FormAuthConfig form;

/**
* The authentication realm
*/
@ConfigItem
public Optional<String> realm;

/**
* If this is true and credentials are present then a user will always be authenticated
* before the request progresses.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.quarkus.vertx.http.runtime;

import java.util.Map;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
Expand All @@ -22,4 +23,16 @@ public class AuthRuntimeConfig {
*/
@ConfigItem(name = "policy")
public Map<String, PolicyConfig> rolePolicy;

/**
* The authentication realm
*/
@ConfigItem
public Optional<String> realm;

/**
* Form Auth config
*/
@ConfigItem
public FormAuthRuntimeConfig form;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package io.quarkus.vertx.http.runtime;

import java.time.Duration;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;

Expand All @@ -11,124 +8,17 @@
*/
@ConfigGroup
public class FormAuthConfig {
/**
* SameSite attribute values for the session and location cookies.
*/
public enum CookieSameSite {
STRICT,
LAX,
NONE
}

/**
* If form authentication is enabled.
*/
@ConfigItem
public boolean enabled;

/**
* The login page. Redirect to login page can be disabled by setting `quarkus.http.auth.form.login-page=`.
*/
@ConfigItem(defaultValue = "/login.html")
public Optional<String> loginPage;

/**
* The post location.
*/
@ConfigItem(defaultValue = "/j_security_check")
public String postLocation;

/**
* The username field name.
*/
@ConfigItem(defaultValue = "j_username")
public String usernameParameter;

/**
* The password field name.
*/
@ConfigItem(defaultValue = "j_password")
public String passwordParameter;

/**
* The error page. Redirect to error page can be disabled by setting `quarkus.http.auth.form.error-page=`.
*/
@ConfigItem(defaultValue = "/error.html")
public Optional<String> errorPage;

/**
* The landing page to redirect to if there is no saved page to redirect back to.
* Redirect to landing page can be disabled by setting `quarkus.http.auth.form.landing-page=`.
*/
@ConfigItem(defaultValue = "/index.html")
public Optional<String> landingPage;

/**
* Option to disable redirect to landingPage if there is no saved page to redirect back to. Form Auth POST is followed
* by redirect to landingPage by default.
*
* @deprecated redirect to landingPage can be disabled by removing default landing page
* (via `quarkus.http.auth.form.landing-page=`). Quarkus will ignore this configuration property
* if there is no landing page.
*/
@ConfigItem(defaultValue = "true")
@Deprecated
public boolean redirectAfterLogin;

/**
* Option to control the name of the cookie used to redirect the user back
* to where he wants to get access to.
*/
@ConfigItem(defaultValue = "quarkus-redirect-location")
public String locationCookie;

/**
* The inactivity (idle) timeout
*
* When inactivity timeout is reached, cookie is not renewed and a new login is enforced.
*/
@ConfigItem(defaultValue = "PT30M")
public Duration timeout;

/**
* How old a cookie can get before it will be replaced with a new cookie with an updated timeout, also
* referred to as "renewal-timeout".
*
* Note that smaller values will result in slightly more server load (as new encrypted cookies will be
* generated more often), however larger values affect the inactivity timeout as the timeout is set
* when a cookie is generated.
*
* For example if this is set to 10 minutes, and the inactivity timeout is 30m, if a users last request
* is when the cookie is 9m old then the actual timeout will happen 21m after the last request, as the timeout
* is only refreshed when a new cookie is generated.
*
* In other words no timeout is tracked on the server side; the timestamp is encoded and encrypted in the cookie itself,
* and it is decrypted and parsed with each request.
*/
@ConfigItem(defaultValue = "PT1M")
public Duration newCookieInterval;

/**
* The cookie that is used to store the persistent session
*/
@ConfigItem(defaultValue = "quarkus-credential")
public String cookieName;

/**
* The cookie path for the session and location cookies.
*/
@ConfigItem(defaultValue = "/")
public Optional<String> cookiePath = Optional.of("/");

/**
* Set the HttpOnly attribute to prevent access to the cookie via JavaScript.
*/
@ConfigItem(defaultValue = "false")
public boolean httpOnlyCookie;

/**
* SameSite attribute for the session and location cookies.
*/
@ConfigItem(defaultValue = "strict")
public CookieSameSite cookieSameSite = CookieSameSite.STRICT;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package io.quarkus.vertx.http.runtime;

import java.time.Duration;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;

/**
* config for the form authentication mechanism
*/
@ConfigGroup
public class FormAuthRuntimeConfig {
/**
* SameSite attribute values for the session and location cookies.
*/
public enum CookieSameSite {
STRICT,
LAX,
NONE
}

/**
* The login page. Redirect to login page can be disabled by setting `quarkus.http.auth.form.login-page=`.
*/
@ConfigItem(defaultValue = "/login.html")
public Optional<String> loginPage;

/**
* The username field name.
*/
@ConfigItem(defaultValue = "j_username")
public String usernameParameter;

/**
* The password field name.
*/
@ConfigItem(defaultValue = "j_password")
public String passwordParameter;

/**
* The error page. Redirect to error page can be disabled by setting `quarkus.http.auth.form.error-page=`.
*/
@ConfigItem(defaultValue = "/error.html")
public Optional<String> errorPage;

/**
* The landing page to redirect to if there is no saved page to redirect back to.
* Redirect to landing page can be disabled by setting `quarkus.http.auth.form.landing-page=`.
*/
@ConfigItem(defaultValue = "/index.html")
public Optional<String> landingPage;

/**
* Option to disable redirect to landingPage if there is no saved page to redirect back to. Form Auth POST is followed
* by redirect to landingPage by default.
*
* @deprecated redirect to landingPage can be disabled by removing default landing page
* (via `quarkus.http.auth.form.landing-page=`). Quarkus will ignore this configuration property
* if there is no landing page.
*/
@ConfigItem(defaultValue = "true")
@Deprecated
public boolean redirectAfterLogin;

/**
* Option to control the name of the cookie used to redirect the user back
* to where he wants to get access to.
*/
@ConfigItem(defaultValue = "quarkus-redirect-location")
public String locationCookie;

/**
* The inactivity (idle) timeout
*
* When inactivity timeout is reached, cookie is not renewed and a new login is enforced.
*/
@ConfigItem(defaultValue = "PT30M")
public Duration timeout;

/**
* How old a cookie can get before it will be replaced with a new cookie with an updated timeout, also
* referred to as "renewal-timeout".
*
* Note that smaller values will result in slightly more server load (as new encrypted cookies will be
* generated more often), however larger values affect the inactivity timeout as the timeout is set
* when a cookie is generated.
*
* For example if this is set to 10 minutes, and the inactivity timeout is 30m, if a users last request
* is when the cookie is 9m old then the actual timeout will happen 21m after the last request, as the timeout
* is only refreshed when a new cookie is generated.
*
* In other words no timeout is tracked on the server side; the timestamp is encoded and encrypted in the cookie itself,
* and it is decrypted and parsed with each request.
*/
@ConfigItem(defaultValue = "PT1M")
public Duration newCookieInterval;

/**
* The cookie that is used to store the persistent session
*/
@ConfigItem(defaultValue = "quarkus-credential")
public String cookieName;

/**
* The cookie path for the session and location cookies.
*/
@ConfigItem(defaultValue = "/")
public Optional<String> cookiePath = Optional.of("/");

/**
* Set the HttpOnly attribute to prevent access to the cookie via JavaScript.
*/
@ConfigItem(defaultValue = "false")
public boolean httpOnlyCookie;

/**
* SameSite attribute for the session and location cookies.
*/
@ConfigItem(defaultValue = "strict")
public CookieSameSite cookieSameSite = CookieSameSite.STRICT;
}
Loading

0 comments on commit 80c11e9

Please sign in to comment.