Search in sources :

Example 1 with CurrentIdentityAssociation

use of io.quarkus.security.identity.CurrentIdentityAssociation in project quarkus by quarkusio.

the class SecurityContextOverrideHandler method updateIdentity.

private void updateIdentity(ResteasyReactiveRequestContext requestContext, SecurityContext modified) {
    requestContext.requireCDIRequestScope();
    InjectableInstance<CurrentIdentityAssociation> instance = getCurrentIdentityAssociation();
    if (instance.isResolvable()) {
        CurrentIdentityAssociation currentIdentityAssociation = instance.get();
        Uni<SecurityIdentity> oldIdentity = currentIdentityAssociation.getDeferredIdentity();
        currentIdentityAssociation.setIdentity(oldIdentity.map(new Function<SecurityIdentity, SecurityIdentity>() {

            @Override
            public SecurityIdentity apply(SecurityIdentity old) {
                Set<Credential> oldCredentials = old.getCredentials();
                Map<String, Object> oldAttributes = old.getAttributes();
                return new SecurityIdentity() {

                    @Override
                    public Principal getPrincipal() {
                        return modified.getUserPrincipal();
                    }

                    @Override
                    public boolean isAnonymous() {
                        return modified.getUserPrincipal() == null;
                    }

                    @Override
                    public Set<String> getRoles() {
                        throw new UnsupportedOperationException("retrieving all roles not supported when JAX-RS security context has been replaced");
                    }

                    @Override
                    public boolean hasRole(String role) {
                        return modified.isUserInRole(role);
                    }

                    @SuppressWarnings("unchecked")
                    @Override
                    public <T extends Credential> T getCredential(Class<T> credentialType) {
                        for (Credential cred : getCredentials()) {
                            if (credentialType.isAssignableFrom(cred.getClass())) {
                                return (T) cred;
                            }
                        }
                        return null;
                    }

                    @Override
                    public Set<Credential> getCredentials() {
                        return oldCredentials;
                    }

                    @SuppressWarnings("unchecked")
                    @Override
                    public <T> T getAttribute(String name) {
                        return (T) oldAttributes.get(name);
                    }

                    @Override
                    public Map<String, Object> getAttributes() {
                        return oldAttributes;
                    }

                    @Override
                    public Uni<Boolean> checkPermission(Permission permission) {
                        return Uni.createFrom().nullItem();
                    }
                };
            }
        }));
    }
}
Also used : Credential(io.quarkus.security.credential.Credential) SecurityIdentity(io.quarkus.security.identity.SecurityIdentity) Function(java.util.function.Function) CurrentIdentityAssociation(io.quarkus.security.identity.CurrentIdentityAssociation) Permission(java.security.Permission) ResourceClass(org.jboss.resteasy.reactive.common.model.ResourceClass)

Example 2 with CurrentIdentityAssociation

use of io.quarkus.security.identity.CurrentIdentityAssociation 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 3 with CurrentIdentityAssociation

use of io.quarkus.security.identity.CurrentIdentityAssociation in project quarkus by quarkusio.

the class ResteasyReactiveRecorder method createDeployment.

public RuntimeValue<Deployment> createDeployment(DeploymentInfo info, BeanContainer beanContainer, ShutdownContext shutdownContext, HttpBuildTimeConfig vertxConfig, RequestContextFactory contextFactory, BeanFactory<ResteasyReactiveInitialiser> initClassFactory, LaunchMode launchMode, boolean resumeOn404) {
    if (resumeOn404) {
        info.setResumeOn404(true);
    }
    CurrentRequestManager.setCurrentRequestInstance(new QuarkusCurrentRequest(beanContainer.instance(CurrentVertxRequest.class)));
    BlockingOperationSupport.setIoThreadDetector(new BlockingOperationSupport.IOThreadDetector() {

        @Override
        public boolean isBlockingAllowed() {
            return BlockingOperationControl.isBlockingAllowed();
        }
    });
    Consumer<Closeable> closeTaskHandler = new Consumer<Closeable>() {

        @Override
        public void accept(Closeable closeable) {
            shutdownContext.addShutdownTask(new ShutdownContext.CloseRunnable(closeable));
        }
    };
    CurrentIdentityAssociation currentIdentityAssociation = Arc.container().instance(CurrentIdentityAssociation.class).get();
    ClassLoader tccl = Thread.currentThread().getContextClassLoader();
    if (contextFactory == null) {
        contextFactory = new RequestContextFactory() {

            @Override
            public ResteasyReactiveRequestContext createContext(Deployment deployment, ProvidersImpl providers, Object context, ThreadSetupAction requestContext, ServerRestHandler[] handlerChain, ServerRestHandler[] abortHandlerChain) {
                return new QuarkusResteasyReactiveRequestContext(deployment, providers, (RoutingContext) context, requestContext, handlerChain, abortHandlerChain, launchMode == LaunchMode.DEVELOPMENT ? tccl : null, currentIdentityAssociation);
            }
        };
    }
    RuntimeDeploymentManager runtimeDeploymentManager = new RuntimeDeploymentManager(info, EXECUTOR_SUPPLIER, closeTaskHandler, contextFactory, new ArcThreadSetupAction(beanContainer.requestContext()), vertxConfig.rootPath);
    Deployment deployment = runtimeDeploymentManager.deploy();
    initClassFactory.createInstance().getInstance().init(deployment);
    currentDeployment = deployment;
    if (LaunchMode.current() == LaunchMode.DEVELOPMENT) {
        classMappers = deployment.getClassMappers();
        RuntimeResourceVisitor.visitRuntimeResources(classMappers, ScoreSystem.ScoreVisitor);
    }
    return new RuntimeValue<>(deployment);
}
Also used : Closeable(java.io.Closeable) RuntimeDeploymentManager(org.jboss.resteasy.reactive.server.core.startup.RuntimeDeploymentManager) Deployment(org.jboss.resteasy.reactive.server.core.Deployment) ArcThreadSetupAction(io.quarkus.resteasy.reactive.common.runtime.ArcThreadSetupAction) ProvidersImpl(org.jboss.resteasy.reactive.server.jaxrs.ProvidersImpl) ArcThreadSetupAction(io.quarkus.resteasy.reactive.common.runtime.ArcThreadSetupAction) ThreadSetupAction(org.jboss.resteasy.reactive.spi.ThreadSetupAction) ServerRestHandler(org.jboss.resteasy.reactive.server.spi.ServerRestHandler) RoutingContext(io.vertx.ext.web.RoutingContext) Consumer(java.util.function.Consumer) BlockingOperationSupport(org.jboss.resteasy.reactive.server.core.BlockingOperationSupport) ShutdownContext(io.quarkus.runtime.ShutdownContext) RequestContextFactory(org.jboss.resteasy.reactive.server.core.RequestContextFactory) ResteasyReactiveRequestContext(org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext) CurrentIdentityAssociation(io.quarkus.security.identity.CurrentIdentityAssociation) RuntimeValue(io.quarkus.runtime.RuntimeValue)

Example 4 with CurrentIdentityAssociation

use of io.quarkus.security.identity.CurrentIdentityAssociation in project quarkus by quarkusio.

the class WebsocketCoreRecorder method createServerContainer.

public RuntimeValue<ServerWebSocketContainer> createServerContainer(BeanContainer beanContainer, RuntimeValue<WebSocketDeploymentInfo> infoVal, ServerWebSocketContainerFactory serverContainerFactory) throws DeploymentException {
    WebSocketDeploymentInfo info = infoVal.getValue();
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    ManagedContext requestContext = Arc.container().requestContext();
    if (serverContainerFactory == null) {
        serverContainerFactory = ServerWebSocketContainer::new;
    }
    Instance<CurrentIdentityAssociation> currentIdentityAssociation = Arc.container().select(CurrentIdentityAssociation.class);
    ServerWebSocketContainer container = serverContainerFactory.create(new ObjectIntrospecter() {

        @Override
        public <T> ObjectFactory<T> createInstanceFactory(Class<T> clazz) {
            BeanContainer.Factory<T> factory = beanContainer.instanceFactory(clazz);
            return new ObjectFactory<T>() {

                @Override
                public ObjectHandle<T> createInstance() {
                    BeanContainer.Instance<T> instance = factory.create();
                    return new ObjectHandle<T>() {

                        @Override
                        public T getInstance() {
                            return instance.get();
                        }

                        @Override
                        public void release() {
                            instance.close();
                        }
                    };
                }
            };
        }
    }, Thread.currentThread().getContextClassLoader(), new Supplier<EventLoopGroup>() {

        @Override
        public EventLoopGroup get() {
            return ((VertxInternal) VertxCoreRecorder.getVertx().get()).getEventLoopGroup();
        }
    }, Collections.singletonList(new ContextSetupHandler() {

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

                CurrentIdentityAssociation getCurrentIdentityAssociation() {
                    if (currentIdentityAssociation.isResolvable()) {
                        return currentIdentityAssociation.get();
                    }
                    return null;
                }

                @Override
                public T call(C context, UndertowSession session) throws Exception {
                    ClassLoader old = Thread.currentThread().getContextClassLoader();
                    Thread.currentThread().setContextClassLoader(cl);
                    boolean required = !requestContext.isActive();
                    if (required) {
                        requestContext.activate();
                        Principal p = session.getUserPrincipal();
                        if (p instanceof WebSocketPrincipal) {
                            var current = getCurrentIdentityAssociation();
                            if (current != null) {
                                current.setIdentity(((WebSocketPrincipal) p).getSecurityIdentity());
                            }
                        }
                    }
                    try {
                        return action.call(context, session);
                    } finally {
                        try {
                            if (required) {
                                requestContext.terminate();
                            }
                        } finally {
                            Thread.currentThread().setContextClassLoader(old);
                        }
                    }
                }
            };
        }
    }), info.isDispatchToWorkerThread(), null, null, info.getExecutor(), Collections.emptyList(), info.getMaxFrameSize(), new Supplier<Principal>() {

        @Override
        public Principal get() {
            if (currentIdentityAssociation.isResolvable()) {
                return new WebSocketPrincipal(currentIdentityAssociation.get().getIdentity());
            }
            return null;
        }
    });
    for (Class<?> i : info.getAnnotatedEndpoints()) {
        container.addEndpoint(i);
    }
    for (ServerEndpointConfig i : info.getProgramaticEndpoints()) {
        container.addEndpoint(i);
    }
    UndertowContainerProvider.setDefaultContainer(container);
    return new RuntimeValue<>(container);
}
Also used : ContextSetupHandler(io.undertow.websockets.util.ContextSetupHandler) Instance(javax.enterprise.inject.Instance) ObjectFactory(io.undertow.websockets.util.ObjectFactory) ObjectFactory(io.undertow.websockets.util.ObjectFactory) ServerWebSocketContainer(io.undertow.websockets.ServerWebSocketContainer) ServerEndpointConfig(javax.websocket.server.ServerEndpointConfig) ObjectIntrospecter(io.undertow.websockets.util.ObjectIntrospecter) WebSocketDeploymentInfo(io.undertow.websockets.WebSocketDeploymentInfo) ObjectHandle(io.undertow.websockets.util.ObjectHandle) EventLoopGroup(io.netty.channel.EventLoopGroup) CurrentIdentityAssociation(io.quarkus.security.identity.CurrentIdentityAssociation) ManagedContext(io.quarkus.arc.ManagedContext) UndertowSession(io.undertow.websockets.UndertowSession) RuntimeValue(io.quarkus.runtime.RuntimeValue) Principal(java.security.Principal)

Example 5 with CurrentIdentityAssociation

use of io.quarkus.security.identity.CurrentIdentityAssociation in project quarkus by quarkusio.

the class UndertowDeploymentRecorder method createDeployment.

public RuntimeValue<DeploymentInfo> createDeployment(String name, Set<String> knownFile, Set<String> knownDirectories, LaunchMode launchMode, ShutdownContext context, String mountPoint, String defaultCharset, String requestCharacterEncoding, String responseCharacterEncoding, boolean proactiveAuth, List<String> welcomeFiles) {
    DeploymentInfo d = new DeploymentInfo();
    d.setDefaultRequestEncoding(requestCharacterEncoding);
    d.setDefaultResponseEncoding(responseCharacterEncoding);
    d.setDefaultEncoding(defaultCharset);
    d.setSessionIdGenerator(new QuarkusSessionIdGenerator());
    d.setClassLoader(getClass().getClassLoader());
    d.setDeploymentName(name);
    d.setContextPath(mountPoint);
    d.setEagerFilterInit(true);
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    if (cl == null) {
        cl = new ClassLoader() {
        };
    }
    d.setClassLoader(cl);
    // TODO: we need better handling of static resources
    ResourceManager resourceManager;
    if (hotDeploymentResourcePaths == null) {
        resourceManager = new KnownPathResourceManager(knownFile, knownDirectories, new ClassPathResourceManager(d.getClassLoader(), "META-INF/resources"));
    } else {
        List<ResourceManager> managers = new ArrayList<>();
        for (Path i : hotDeploymentResourcePaths) {
            managers.add(new PathResourceManager(i));
        }
        managers.add(new ClassPathResourceManager(d.getClassLoader(), "META-INF/resources"));
        resourceManager = new DelegatingResourceManager(managers.toArray(new ResourceManager[0]));
    }
    if (launchMode == LaunchMode.NORMAL) {
        // todo: cache configuration
        resourceManager = new CachingResourceManager(1000, 0, null, resourceManager, 2000);
    }
    d.setResourceManager(resourceManager);
    if (welcomeFiles != null) {
        // if available, use welcome-files from web.xml
        d.addWelcomePages(welcomeFiles);
    } else {
        d.addWelcomePages("index.html", "index.htm");
    }
    d.addServlet(new ServletInfo(ServletPathMatches.DEFAULT_SERVLET_NAME, DefaultServlet.class).setAsyncSupported(true));
    for (HandlerWrapper i : hotDeploymentWrappers) {
        d.addOuterHandlerChainWrapper(i);
    }
    d.addAuthenticationMechanism("QUARKUS", new ImmediateAuthenticationMechanismFactory(QuarkusAuthMechanism.INSTANCE));
    d.setLoginConfig(new LoginConfig("QUARKUS", "QUARKUS"));
    context.addShutdownTask(new ShutdownContext.CloseRunnable(d.getResourceManager()));
    d.addNotificationReceiver(new NotificationReceiver() {

        @Override
        public void handleNotification(SecurityNotification notification) {
            if (notification.getEventType() == SecurityNotification.EventType.AUTHENTICATED) {
                QuarkusUndertowAccount account = (QuarkusUndertowAccount) notification.getAccount();
                Instance<CurrentIdentityAssociation> instance = CDI.current().select(CurrentIdentityAssociation.class);
                if (instance.isResolvable())
                    instance.get().setIdentity(account.getSecurityIdentity());
            }
        }
    });
    if (proactiveAuth) {
        d.setAuthenticationMode(AuthenticationMode.PRO_ACTIVE);
    } else {
        d.setAuthenticationMode(AuthenticationMode.CONSTRAINT_DRIVEN);
    }
    return new RuntimeValue<>(d);
}
Also used : Instance(javax.enterprise.inject.Instance) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) HandlerWrapper(io.undertow.server.HandlerWrapper) ClassPathResourceManager(io.undertow.server.handlers.resource.ClassPathResourceManager) PathResourceManager(io.undertow.server.handlers.resource.PathResourceManager) SecurityNotification(io.undertow.security.api.SecurityNotification) ServletInfo(io.undertow.servlet.api.ServletInfo) ShutdownContext(io.quarkus.runtime.ShutdownContext) LoginConfig(io.undertow.servlet.api.LoginConfig) CachingResourceManager(io.undertow.server.handlers.resource.CachingResourceManager) DeploymentInfo(io.undertow.servlet.api.DeploymentInfo) Path(java.nio.file.Path) ImmediateAuthenticationMechanismFactory(io.undertow.util.ImmediateAuthenticationMechanismFactory) ClassPathResourceManager(io.undertow.server.handlers.resource.ClassPathResourceManager) PathResourceManager(io.undertow.server.handlers.resource.PathResourceManager) ResourceManager(io.undertow.server.handlers.resource.ResourceManager) CachingResourceManager(io.undertow.server.handlers.resource.CachingResourceManager) NotificationReceiver(io.undertow.security.api.NotificationReceiver) CurrentIdentityAssociation(io.quarkus.security.identity.CurrentIdentityAssociation) RuntimeValue(io.quarkus.runtime.RuntimeValue) ClassPathResourceManager(io.undertow.server.handlers.resource.ClassPathResourceManager)

Aggregations

CurrentIdentityAssociation (io.quarkus.security.identity.CurrentIdentityAssociation)5 RuntimeValue (io.quarkus.runtime.RuntimeValue)3 ManagedContext (io.quarkus.arc.ManagedContext)2 ShutdownContext (io.quarkus.runtime.ShutdownContext)2 SecurityIdentity (io.quarkus.security.identity.SecurityIdentity)2 RoutingContext (io.vertx.ext.web.RoutingContext)2 Instance (javax.enterprise.inject.Instance)2 EventLoopGroup (io.netty.channel.EventLoopGroup)1 InjectableContext (io.quarkus.arc.InjectableContext)1 ArcThreadSetupAction (io.quarkus.resteasy.reactive.common.runtime.ArcThreadSetupAction)1 AuthenticationFailedException (io.quarkus.security.AuthenticationFailedException)1 ForbiddenException (io.quarkus.security.ForbiddenException)1 UnauthorizedException (io.quarkus.security.UnauthorizedException)1 Credential (io.quarkus.security.credential.Credential)1 CurrentVertxRequest (io.quarkus.vertx.http.runtime.CurrentVertxRequest)1 QuarkusHttpUser (io.quarkus.vertx.http.runtime.security.QuarkusHttpUser)1 NotificationReceiver (io.undertow.security.api.NotificationReceiver)1 SecurityNotification (io.undertow.security.api.SecurityNotification)1 HandlerWrapper (io.undertow.server.HandlerWrapper)1 HttpServerExchange (io.undertow.server.HttpServerExchange)1