All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.security.webauthn.WebAuthnRecorder Maven / Gradle / Ivy

There is a newer version: 3.17.0.CR1
Show newest version
package io.quarkus.security.webauthn;

import java.security.SecureRandom;
import java.util.Base64;
import java.util.function.Supplier;

import org.jboss.logging.Logger;

import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.security.identity.IdentityProviderManager;
import io.quarkus.vertx.http.runtime.HttpConfiguration;
import io.quarkus.vertx.http.runtime.security.PersistentLoginManager;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;

@Recorder
public class WebAuthnRecorder {

    private static final Logger log = Logger.getLogger(WebAuthnRecorder.class);

    final RuntimeValue httpConfiguration;
    final RuntimeValue config;

    //the temp encryption key, persistent across dev mode restarts
    static volatile String encryptionKey;

    public WebAuthnRecorder(RuntimeValue httpConfiguration, RuntimeValue config) {
        this.httpConfiguration = httpConfiguration;
        this.config = config;
    }

    public void setupRoutes(BeanContainer beanContainer, RuntimeValue routerValue, String prefix) {
        WebAuthnSecurity security = beanContainer.beanInstance(WebAuthnSecurity.class);
        WebAuthnAuthenticationMechanism authMech = beanContainer.beanInstance(WebAuthnAuthenticationMechanism.class);
        IdentityProviderManager identityProviderManager = beanContainer.beanInstance(IdentityProviderManager.class);
        WebAuthnController controller = new WebAuthnController(security, config.getValue(), identityProviderManager, authMech);
        Router router = routerValue.getValue();
        BodyHandler bodyHandler = BodyHandler.create();
        // FIXME: paths configurable
        // prefix is the non-application root path, ends with a slash: defaults to /q/
        router.post(prefix + "webauthn/login").handler(bodyHandler).handler(controller::login);
        router.post(prefix + "webauthn/register").handler(bodyHandler).handler(controller::register);
        router.post(prefix + "webauthn/callback").handler(bodyHandler).handler(controller::callback);
        router.get(prefix + "webauthn/webauthn.js").handler(controller::javascript);
        router.get(prefix + "webauthn/logout").handler(controller::logout);
    }

    public Supplier setupWebAuthnAuthenticationMechanism() {

        return new Supplier() {
            @Override
            public WebAuthnAuthenticationMechanism get() {
                String key;
                if (!httpConfiguration.getValue().encryptionKey.isPresent()) {
                    if (encryptionKey != null) {
                        //persist across dev mode restarts
                        key = encryptionKey;
                    } else {
                        byte[] data = new byte[32];
                        new SecureRandom().nextBytes(data);
                        key = encryptionKey = Base64.getEncoder().encodeToString(data);
                        log.warn(
                                "Encryption key was not specified (using `quarkus.http.auth.session.encryption-key` configuration) for persistent WebAuthn auth, using temporary key "
                                        + key);
                    }
                } else {
                    key = httpConfiguration.getValue().encryptionKey.get();
                }
                WebAuthnRunTimeConfig config = WebAuthnRecorder.this.config.getValue();
                PersistentLoginManager loginManager = new PersistentLoginManager(key, config.cookieName(),
                        config.sessionTimeout().toMillis(),
                        config.newCookieInterval().toMillis(), false, config.cookieSameSite().name(),
                        config.cookiePath().orElse(null));
                String loginPage = config.loginPage().startsWith("/") ? config.loginPage() : "/" + config.loginPage();
                return new WebAuthnAuthenticationMechanism(loginManager, loginPage);
            }
        };
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy