Search in sources :

Example 1 with ManagedContext

use of io.quarkus.arc.ManagedContext in project quarkus by quarkusio.

the class WebAuthnController method login.

/**
 * Endpoint for login
 *
 * @param ctx the current request
 */
public void login(RoutingContext ctx) {
    try {
        // might throw runtime exception if there's no json or is bad formed
        final JsonObject webauthnLogin = ctx.getBodyAsJson();
        if (webauthnLogin == null || !containsRequiredString(webauthnLogin, "name")) {
            ctx.fail(400, new IllegalArgumentException("Request missing 'name' field"));
            return;
        }
        // input basic validation is OK
        final String username = webauthnLogin.getString("name");
        ManagedContext requestContext = Arc.container().requestContext();
        requestContext.activate();
        ContextState contextState = requestContext.getState();
        // STEP 18 Generate assertion
        security.getWebAuthn().getCredentialsOptions(username, generateServerGetAssertion -> {
            requestContext.destroy(contextState);
            if (generateServerGetAssertion.failed()) {
                ctx.fail(generateServerGetAssertion.cause());
                return;
            }
            final JsonObject getAssertion = generateServerGetAssertion.result();
            authMech.getLoginManager().save(getAssertion.getString("challenge"), ctx, CHALLENGE_COOKIE, null, ctx.request().isSSL());
            authMech.getLoginManager().save(username, ctx, USERNAME_COOKIE, null, ctx.request().isSSL());
            ok(ctx, getAssertion);
        });
    } catch (IllegalArgumentException e) {
        ctx.fail(400, e);
    } catch (RuntimeException e) {
        ctx.fail(e);
    }
}
Also used : ContextState(io.quarkus.arc.InjectableContext.ContextState) JsonObject(io.vertx.core.json.JsonObject) ManagedContext(io.quarkus.arc.ManagedContext)

Example 2 with ManagedContext

use of io.quarkus.arc.ManagedContext in project quarkus by quarkusio.

the class WebAuthnController method callback.

/**
 * Endpoint for callback
 *
 * @param ctx the current request
 */
public void callback(RoutingContext ctx) {
    try {
        // might throw runtime exception if there's no json or is bad formed
        final JsonObject webauthnResp = ctx.getBodyAsJson();
        // input validation
        if (webauthnResp == null || !containsRequiredString(webauthnResp, "id") || !containsRequiredString(webauthnResp, "rawId") || !containsRequiredObject(webauthnResp, "response") || !containsOptionalString(webauthnResp.getJsonObject("response"), "userHandle") || !containsRequiredString(webauthnResp, "type") || !"public-key".equals(webauthnResp.getString("type"))) {
            ctx.fail(400, new IllegalArgumentException("Response missing one or more of id/rawId/response[.userHandle]/type fields, or type is not public-key"));
            return;
        }
        RestoreResult challenge = authMech.getLoginManager().restore(ctx, CHALLENGE_COOKIE);
        RestoreResult username = authMech.getLoginManager().restore(ctx, USERNAME_COOKIE);
        if (challenge == null || challenge.getPrincipal() == null || challenge.getPrincipal().isEmpty() || username == null || username.getPrincipal() == null || username.getPrincipal().isEmpty()) {
            ctx.fail(400, new IllegalArgumentException("Missing challenge or username"));
            return;
        }
        ManagedContext requestContext = Arc.container().requestContext();
        requestContext.activate();
        ContextState contextState = requestContext.getState();
        // input basic validation is OK
        // authInfo
        WebAuthnCredentials credentials = new WebAuthnCredentials().setOrigin(origin).setDomain(domain).setChallenge(challenge.getPrincipal()).setUsername(username.getPrincipal()).setWebauthn(webauthnResp);
        identityProviderManager.authenticate(HttpSecurityUtils.setRoutingContextAttribute(new WebAuthnAuthenticationRequest(credentials), ctx)).subscribe().with(new Consumer<SecurityIdentity>() {

            @Override
            public void accept(SecurityIdentity identity) {
                requestContext.destroy(contextState);
                // invalidate the challenge
                WebAuthnSecurity.removeCookie(ctx, WebAuthnController.CHALLENGE_COOKIE);
                WebAuthnSecurity.removeCookie(ctx, WebAuthnController.USERNAME_COOKIE);
                try {
                    authMech.getLoginManager().save(identity, ctx, null, ctx.request().isSSL());
                    ok(ctx);
                } catch (Throwable t) {
                    log.error("Unable to complete post authentication", t);
                    ctx.fail(t);
                }
            }
        }, new Consumer<Throwable>() {

            @Override
            public void accept(Throwable throwable) {
                requestContext.terminate();
                if (throwable instanceof AttestationException) {
                    ctx.fail(400, throwable);
                } else {
                    ctx.fail(throwable);
                }
            }
        });
    } catch (IllegalArgumentException e) {
        ctx.fail(400, e);
    } catch (RuntimeException e) {
        ctx.fail(e);
    }
}
Also used : AttestationException(io.vertx.ext.auth.webauthn.impl.attestation.AttestationException) RestoreResult(io.quarkus.vertx.http.runtime.security.PersistentLoginManager.RestoreResult) JsonObject(io.vertx.core.json.JsonObject) SecurityIdentity(io.quarkus.security.identity.SecurityIdentity) WebAuthnCredentials(io.vertx.ext.auth.webauthn.WebAuthnCredentials) ContextState(io.quarkus.arc.InjectableContext.ContextState) ManagedContext(io.quarkus.arc.ManagedContext)

Example 3 with ManagedContext

use of io.quarkus.arc.ManagedContext in project quarkus by quarkusio.

the class UndertowDeploymentRecorder method setupRequestScope.

public void setupRequestScope(DeploymentInfo deploymentInfo, BeanContainer beanContainer) {
    CurrentVertxRequest currentVertxRequest = CDI.current().select(CurrentVertxRequest.class).get();
    Instance<CurrentIdentityAssociation> identityAssociations = CDI.current().select(CurrentIdentityAssociation.class);
    CurrentIdentityAssociation association;
    if (identityAssociations.isResolvable()) {
        association = identityAssociations.get();
    } else {
        association = null;
    }
    deploymentInfo.addThreadSetupAction(new ThreadSetupHandler() {

        @Override
        public <T, C> ThreadSetupHandler.Action<T, C> create(Action<T, C> action) {
            return new Action<T, C>() {

                @Override
                public T call(HttpServerExchange exchange, C context) throws Exception {
                    // Not sure what to do here
                    ManagedContext requestContext = beanContainer.requestContext();
                    if (requestContext.isActive()) {
                        return action.call(exchange, context);
                    } else if (exchange == null) {
                        requestContext.activate();
                        try {
                            return action.call(exchange, context);
                        } finally {
                            requestContext.terminate();
                        }
                    } else {
                        InjectableContext.ContextState existingRequestContext = exchange.getAttachment(REQUEST_CONTEXT);
                        try {
                            requestContext.activate(existingRequestContext);
                            VertxHttpExchange delegate = (VertxHttpExchange) exchange.getDelegate();
                            RoutingContext rc = (RoutingContext) delegate.getContext();
                            currentVertxRequest.setCurrent(rc);
                            if (association != null) {
                                QuarkusHttpUser existing = (QuarkusHttpUser) rc.user();
                                if (existing != null) {
                                    SecurityIdentity identity = existing.getSecurityIdentity();
                                    association.setIdentity(identity);
                                } else {
                                    association.setIdentity(QuarkusHttpUser.getSecurityIdentity(rc, null));
                                }
                            }
                            return action.call(exchange, context);
                        } finally {
                            ServletRequestContext src = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
                            HttpServletRequestImpl req = src.getOriginalRequest();
                            if (req.isAsyncStarted()) {
                                exchange.putAttachment(REQUEST_CONTEXT, requestContext.getState());
                                requestContext.deactivate();
                                if (existingRequestContext == null) {
                                    req.getAsyncContextInternal().addListener(new AsyncListener() {

                                        @Override
                                        public void onComplete(AsyncEvent event) throws IOException {
                                            requestContext.activate(exchange.getAttachment(REQUEST_CONTEXT));
                                            requestContext.terminate();
                                        }

                                        @Override
                                        public void onTimeout(AsyncEvent event) throws IOException {
                                            onComplete(event);
                                        }

                                        @Override
                                        public void onError(AsyncEvent event) throws IOException {
                                            onComplete(event);
                                        }

                                        @Override
                                        public void onStartAsync(AsyncEvent event) throws IOException {
                                        }
                                    });
                                }
                            } else {
                                requestContext.terminate();
                            }
                        }
                    }
                }
            };
        }
    });
}
Also used : InjectableContext(io.quarkus.arc.InjectableContext) ServletRequestContext(io.undertow.servlet.handlers.ServletRequestContext) IOException(java.io.IOException) CurrentVertxRequest(io.quarkus.vertx.http.runtime.CurrentVertxRequest) AsyncEvent(javax.servlet.AsyncEvent) AuthenticationFailedException(io.quarkus.security.AuthenticationFailedException) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) ForbiddenException(io.quarkus.security.ForbiddenException) UnauthorizedException(io.quarkus.security.UnauthorizedException) HttpServerExchange(io.undertow.server.HttpServerExchange) SecurityIdentity(io.quarkus.security.identity.SecurityIdentity) ThreadSetupHandler(io.undertow.servlet.api.ThreadSetupHandler) VertxHttpExchange(io.undertow.vertx.VertxHttpExchange) RoutingContext(io.vertx.ext.web.RoutingContext) HttpServletRequestImpl(io.undertow.servlet.spec.HttpServletRequestImpl) CurrentIdentityAssociation(io.quarkus.security.identity.CurrentIdentityAssociation) AsyncListener(javax.servlet.AsyncListener) ManagedContext(io.quarkus.arc.ManagedContext) QuarkusHttpUser(io.quarkus.vertx.http.runtime.security.QuarkusHttpUser)

Example 4 with ManagedContext

use of io.quarkus.arc.ManagedContext in project quarkus by quarkusio.

the class RequestContextTest method testRequestContextEvents.

@Test
public void testRequestContextEvents() {
    // reset counters since other tests might have triggered it already
    ContextObserver.reset();
    // firstly test manual activation
    ArcContainer arc = Arc.container();
    ManagedContext requestContext = arc.requestContext();
    try {
        arc.instance(Controller.class).get().getId();
        fail();
    } catch (ContextNotActiveException expected) {
    }
    requestContext.activate();
    assertEquals(1, ContextObserver.initializedObserved);
    assertEquals(0, ContextObserver.beforeDestroyedObserved);
    assertEquals(0, ContextObserver.destroyedObserved);
    // dummy check that bean is available
    arc.instance(Controller.class).get().getId();
    requestContext.terminate();
    assertEquals(1, ContextObserver.initializedObserved);
    assertEquals(1, ContextObserver.beforeDestroyedObserved);
    assertEquals(1, ContextObserver.destroyedObserved);
    try {
        arc.instance(Controller.class).get().getId();
        fail();
    } catch (ContextNotActiveException expected) {
    }
    // now test the same but activate context via interceptor (@ActivateRequestContext)
    arc.instance(ControllerClient.class).get().getControllerId();
    assertEquals(2, ContextObserver.initializedObserved);
    assertEquals(2, ContextObserver.beforeDestroyedObserved);
    assertEquals(2, ContextObserver.destroyedObserved);
    // lastly, use RequestContextController bean to handle the context
    try {
        arc.instance(Controller.class).get().getId();
        fail();
    } catch (ContextNotActiveException expected) {
    }
    RequestContextController controller = arc.instance(RequestContextController.class).get();
    controller.activate();
    assertEquals(3, ContextObserver.initializedObserved);
    assertEquals(2, ContextObserver.beforeDestroyedObserved);
    assertEquals(2, ContextObserver.destroyedObserved);
    // dummy check that bean is available
    arc.instance(Controller.class).get().getId();
    controller.deactivate();
    assertEquals(3, ContextObserver.initializedObserved);
    assertEquals(3, ContextObserver.beforeDestroyedObserved);
    assertEquals(3, ContextObserver.destroyedObserved);
    try {
        arc.instance(Controller.class).get().getId();
        fail();
    } catch (ContextNotActiveException expected) {
    }
}
Also used : ArcContainer(io.quarkus.arc.ArcContainer) ContextNotActiveException(javax.enterprise.context.ContextNotActiveException) ManagedContext(io.quarkus.arc.ManagedContext) RequestContextController(javax.enterprise.context.control.RequestContextController) Test(org.junit.jupiter.api.Test)

Example 5 with ManagedContext

use of io.quarkus.arc.ManagedContext in project quarkus by quarkusio.

the class RequestContextTest method testRequestContext.

@Test
public void testRequestContext() {
    Controller.DESTROYED.set(false);
    ArcContainer arc = Arc.container();
    ManagedContext requestContext = arc.requestContext();
    try {
        arc.instance(Controller.class).get().getId();
        fail();
    } catch (ContextNotActiveException expected) {
    }
    requestContext.activate();
    assertFalse(Controller.DESTROYED.get());
    Controller controller1 = arc.instance(Controller.class).get();
    Controller controller2 = arc.instance(Controller.class).get();
    String controller2Id = controller2.getId();
    assertEquals(controller1.getId(), controller2Id);
    requestContext.terminate();
    assertTrue(Controller.DESTROYED.get());
    try {
        arc.instance(Controller.class).get().getId();
        fail();
    } catch (ContextNotActiveException expected) {
    }
    // Id must be different in a different request
    Controller.DESTROYED.set(false);
    requestContext.activate();
    assertNotEquals(controller2Id, arc.instance(Controller.class).get().getId());
    requestContext.terminate();
    assertTrue(Controller.DESTROYED.get());
    Controller.DESTROYED.set(false);
    requestContext.activate();
    assertNotEquals(controller2Id, arc.instance(Controller.class).get().getId());
    requestContext.terminate();
    assertTrue(Controller.DESTROYED.get());
    // @ActivateRequestContext
    Controller.DESTROYED.set(false);
    ControllerClient client = arc.instance(ControllerClient.class).get();
    assertNotEquals(controller2Id, client.getControllerId());
    assertTrue(Controller.DESTROYED.get());
}
Also used : ArcContainer(io.quarkus.arc.ArcContainer) ContextNotActiveException(javax.enterprise.context.ContextNotActiveException) ManagedContext(io.quarkus.arc.ManagedContext) RequestContextController(javax.enterprise.context.control.RequestContextController) Test(org.junit.jupiter.api.Test)

Aggregations

ManagedContext (io.quarkus.arc.ManagedContext)29 Test (org.junit.jupiter.api.Test)8 ArcContainer (io.quarkus.arc.ArcContainer)7 ContextState (io.quarkus.arc.InjectableContext.ContextState)6 SecurityIdentity (io.quarkus.security.identity.SecurityIdentity)6 QuarkusHttpUser (io.quarkus.vertx.http.runtime.security.QuarkusHttpUser)5 RequestContextImpl (io.quarkus.funqy.runtime.RequestContextImpl)4 JsonObject (io.vertx.core.json.JsonObject)3 ContextNotActiveException (javax.enterprise.context.ContextNotActiveException)3 GET (javax.ws.rs.GET)3 Path (javax.ws.rs.Path)3 InjectableContext (io.quarkus.arc.InjectableContext)2 CurrentIdentityAssociation (io.quarkus.security.identity.CurrentIdentityAssociation)2 RoutingContext (io.vertx.ext.web.RoutingContext)2 IOException (java.io.IOException)2 RequestContextController (javax.enterprise.context.control.RequestContextController)2 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ObjectWriter (com.fasterxml.jackson.databind.ObjectWriter)1 ServerCall (io.grpc.ServerCall)1 EventLoopGroup (io.netty.channel.EventLoopGroup)1