Search in sources :

Example 1 with InterceptorContext

use of org.jboss.invocation.InterceptorContext in project wildfly by wildfly.

the class ApplicationClientComponentDescription method createConfiguration.

@Override
public ComponentConfiguration createConfiguration(final ClassReflectionIndex classIndex, final ClassLoader moduleClassLoader, final ModuleLoader moduleLoader) {
    final ComponentConfiguration configuration = super.createConfiguration(classIndex, moduleClassLoader, moduleLoader);
    configuration.setInstanceFactory(new ComponentFactory() {

        @Override
        public ManagedReference create(final InterceptorContext context) {
            return new ManagedReference() {

                @Override
                public void release() {
                }

                @Override
                public Object getInstance() {
                    return null;
                }
            };
        }
    });
    return configuration;
}
Also used : ComponentConfiguration(org.jboss.as.ee.component.ComponentConfiguration) ComponentFactory(org.jboss.as.ee.component.ComponentFactory) InterceptorContext(org.jboss.invocation.InterceptorContext) ManagedReference(org.jboss.as.naming.ManagedReference)

Example 2 with InterceptorContext

use of org.jboss.invocation.InterceptorContext in project wildfly by wildfly.

the class EjbCorbaServant method invoke.

// Implementation of the interface LocalIIOPInvoker ------------------------
/**
     * Receives intra-VM invocations on this servant's <code>EJBObject</code>s
     * and forwards them to the bean container, through the JBoss
     * <code>MBean</code>
     * server.
     */
public Object invoke(String opName, Object[] arguments, Transaction tx, Principal identity, Object credential) throws Exception {
    EjbLogger.ROOT_LOGGER.tracef("EJBObject local invocation: %s", opName);
    SkeletonStrategy op = methodInvokerMap.get(opName);
    if (op == null) {
        throw new BAD_OPERATION(opName);
    }
    if (tx != null) {
        transactionManager.resume(tx);
    }
    try {
        final InterceptorContext interceptorContext = new InterceptorContext();
        prepareInterceptorContext(op, arguments, interceptorContext);
        return componentView.invoke(interceptorContext);
    } finally {
        if (tx != null) {
            if (transactionManager.getStatus() != Status.STATUS_NO_TRANSACTION) {
                transactionManager.suspend();
            }
        }
    }
}
Also used : InterceptorContext(org.jboss.invocation.InterceptorContext) SkeletonStrategy(org.wildfly.iiop.openjdk.rmi.marshal.strategy.SkeletonStrategy) BAD_OPERATION(org.omg.CORBA.BAD_OPERATION)

Example 3 with InterceptorContext

use of org.jboss.invocation.InterceptorContext in project wildfly by wildfly.

the class EjbCorbaServant method _invoke.

/**
     * Receives IIOP requests to this servant's <code>EJBObject</code>s
     * and forwards them to the bean container, through the JBoss
     * <code>MBean</code> server.
     */
public OutputStream _invoke(final String opName, final InputStream in, final ResponseHandler handler) {
    EjbLogger.ROOT_LOGGER.tracef("EJBObject invocation: %s", opName);
    SkeletonStrategy op = methodInvokerMap.get(opName);
    if (op == null) {
        EjbLogger.ROOT_LOGGER.debugf("Unable to find opname '%s' valid operations:%s", opName, methodInvokerMap.keySet());
        throw new BAD_OPERATION(opName);
    }
    final NamespaceContextSelector selector = componentView.getComponent().getNamespaceContextSelector();
    final ClassLoader oldCl = WildFlySecurityManager.getCurrentContextClassLoaderPrivileged();
    NamespaceContextSelector.pushCurrentSelector(selector);
    try {
        WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(classLoader);
        org.omg.CORBA_2_3.portable.OutputStream out;
        try {
            Object retVal;
            if (!home && opName.equals("_get_handle")) {
                retVal = new HandleImplIIOP(orb.object_to_string(_this_object()));
            } else if (home && opName.equals("_get_homeHandle")) {
                retVal = homeHandle;
            } else if (home && opName.equals("_get_EJBMetaData")) {
                retVal = ejbMetaData;
            } else {
                Principal identityPrincipal = null;
                Principal principal = null;
                Object credential = null;
                if (this.sasCurrent != null) {
                    final byte[] incomingIdentity = this.sasCurrent.get_incoming_principal_name();
                    //we have an identity token, which is a trust based mechanism
                    if (incomingIdentity != null && incomingIdentity.length > 0) {
                        String name = new String(incomingIdentity, StandardCharsets.UTF_8);
                        int domainIndex = name.indexOf('@');
                        if (domainIndex > 0)
                            name = name.substring(0, domainIndex);
                        identityPrincipal = new NamePrincipal(name);
                    }
                    final byte[] incomingUsername = this.sasCurrent.get_incoming_username();
                    if (incomingUsername != null && incomingUsername.length > 0) {
                        final byte[] incomingPassword = this.sasCurrent.get_incoming_password();
                        String name = new String(incomingUsername, StandardCharsets.UTF_8);
                        int domainIndex = name.indexOf('@');
                        if (domainIndex > 0) {
                            name = name.substring(0, domainIndex);
                        }
                        principal = new NamePrincipal(name);
                        credential = new String(incomingPassword, StandardCharsets.UTF_8).toCharArray();
                    }
                }
                final Object[] params = op.readParams((org.omg.CORBA_2_3.portable.InputStream) in);
                if (!this.home && opName.equals("isIdentical") && params.length == 1) {
                    //handle isIdentical specially
                    Object val = params[0];
                    retVal = val instanceof org.omg.CORBA.Object && handleIsIdentical((org.omg.CORBA.Object) val);
                } else {
                    if (this.securityDomain != null) {
                        // an elytron security domain is available: authenticate and authorize the client before invoking the component.
                        SecurityIdentity identity = this.securityDomain.getAnonymousSecurityIdentity();
                        AuthenticationConfiguration authenticationConfiguration = AuthenticationConfiguration.EMPTY;
                        if (identityPrincipal != null) {
                            // permission to run as the identity token principal.
                            if (principal != null) {
                                char[] password = (char[]) credential;
                                authenticationConfiguration = authenticationConfiguration.useName(principal.getName()).usePassword(password);
                                SecurityIdentity authenticatedIdentity = this.authenticate(principal, password);
                                identity = authenticatedIdentity.createRunAsIdentity(identityPrincipal.getName(), true);
                            } else {
                                // no TLS nor initial context token found - check if the anonymous identity has
                                // permission to run as the identity principal.
                                identity = this.securityDomain.getAnonymousSecurityIdentity().createRunAsIdentity(identityPrincipal.getName(), true);
                            }
                        } else if (principal != null) {
                            char[] password = (char[]) credential;
                            // we have an initial context token containing a username/password pair.
                            authenticationConfiguration = authenticationConfiguration.useName(principal.getName()).usePassword(password);
                            identity = this.authenticate(principal, password);
                        }
                        final InterceptorContext interceptorContext = new InterceptorContext();
                        this.prepareInterceptorContext(op, params, interceptorContext);
                        try {
                            final AuthenticationContext context = AuthenticationContext.captureCurrent().with(MatchRule.ALL.matchProtocol("iiop"), authenticationConfiguration);
                            retVal = identity.runAs((PrivilegedExceptionAction<Object>) () -> context.run((PrivilegedExceptionAction<Object>) () -> this.componentView.invoke(interceptorContext)));
                        } catch (PrivilegedActionException e) {
                            throw e.getCause();
                        }
                    } else {
                        // legacy security behavior: setup the security context if a SASCurrent is available and invoke the component.
                        // One of the EJB security interceptors will authenticate and authorize the client.
                        SecurityContext legacyContext = null;
                        if (this.legacySecurityDomain != null && (identityPrincipal != null || principal != null)) {
                            // we don't have any real way to establish trust in identity based auth so we just use
                            // the SASCurrent as a credential, and a custom legacy login module can make a decision for us.
                            final Object finalCredential = identityPrincipal != null ? this.sasCurrent : credential;
                            final Principal finalPrincipal = identityPrincipal != null ? identityPrincipal : principal;
                            if (WildFlySecurityManager.isChecking()) {
                                legacyContext = AccessController.doPrivileged((PrivilegedExceptionAction<SecurityContext>) () -> {
                                    SecurityContext sc = SecurityContextFactory.createSecurityContext(this.legacySecurityDomain);
                                    sc.getUtil().createSubjectInfo(finalPrincipal, finalCredential, null);
                                    return sc;
                                });
                            } else {
                                legacyContext = SecurityContextFactory.createSecurityContext(this.legacySecurityDomain);
                                legacyContext.getUtil().createSubjectInfo(finalPrincipal, finalCredential, null);
                            }
                        }
                        if (legacyContext != null) {
                            setSecurityContextOnAssociation(legacyContext);
                        }
                        try {
                            final InterceptorContext interceptorContext = new InterceptorContext();
                            if (legacyContext != null) {
                                interceptorContext.putPrivateData(SecurityContext.class, legacyContext);
                            }
                            prepareInterceptorContext(op, params, interceptorContext);
                            retVal = this.componentView.invoke(interceptorContext);
                        } finally {
                            if (legacyContext != null) {
                                clearSecurityContextOnAssociation();
                            }
                        }
                    }
                }
            }
            out = (org.omg.CORBA_2_3.portable.OutputStream) handler.createReply();
            if (op.isNonVoid()) {
                op.writeRetval(out, retVal);
            }
        } catch (Throwable e) {
            EjbLogger.ROOT_LOGGER.trace("Exception in EJBObject invocation", e);
            if (e instanceof MBeanException) {
                e = ((MBeanException) e).getTargetException();
            }
            RmiIdlUtil.rethrowIfCorbaSystemException(e);
            out = (org.omg.CORBA_2_3.portable.OutputStream) handler.createExceptionReply();
            op.writeException(out, e);
        }
        return out;
    } finally {
        NamespaceContextSelector.popCurrentSelector();
        WildFlySecurityManager.setCurrentContextClassLoaderPrivileged(oldCl);
    }
}
Also used : ServerAuthenticationContext(org.wildfly.security.auth.server.ServerAuthenticationContext) AuthenticationContext(org.wildfly.security.auth.client.AuthenticationContext) NamePrincipal(org.wildfly.security.auth.principal.NamePrincipal) OutputStream(org.omg.CORBA.portable.OutputStream) NamespaceContextSelector(org.jboss.as.naming.context.NamespaceContextSelector) HandleImplIIOP(org.jboss.ejb.iiop.HandleImplIIOP) InterceptorContext(org.jboss.invocation.InterceptorContext) AuthenticationConfiguration(org.wildfly.security.auth.client.AuthenticationConfiguration) PrivilegedActionException(java.security.PrivilegedActionException) SkeletonStrategy(org.wildfly.iiop.openjdk.rmi.marshal.strategy.SkeletonStrategy) PrivilegedExceptionAction(java.security.PrivilegedExceptionAction) SecurityIdentity(org.wildfly.security.auth.server.SecurityIdentity) SecurityContext(org.jboss.security.SecurityContext) MBeanException(javax.management.MBeanException) BAD_OPERATION(org.omg.CORBA.BAD_OPERATION) NamePrincipal(org.wildfly.security.auth.principal.NamePrincipal) Principal(java.security.Principal)

Example 4 with InterceptorContext

use of org.jboss.invocation.InterceptorContext in project wildfly by wildfly.

the class LocalEjbReceiver method processInvocation.

@Override
protected void processInvocation(final EJBReceiverInvocationContext receiverContext) {
    final EJBClientInvocationContext invocation = receiverContext.getClientInvocationContext();
    final EJBLocator<?> locator = invocation.getLocator();
    final EjbDeploymentInformation ejb = findBean(locator);
    final EJBComponent ejbComponent = ejb.getEjbComponent();
    final Class<?> viewClass = invocation.getViewClass();
    final ComponentView view = ejb.getView(viewClass.getName());
    if (view == null) {
        throw EjbLogger.ROOT_LOGGER.viewNotFound(viewClass.getName(), ejb.getEjbName());
    }
    // make sure it's a remote view
    if (!ejb.isRemoteView(viewClass.getName())) {
        throw EjbLogger.ROOT_LOGGER.viewNotFound(viewClass.getName(), ejb.getEjbName());
    }
    final ClonerConfiguration paramConfig = new ClonerConfiguration();
    paramConfig.setClassCloner(new ClassLoaderClassCloner(ejb.getDeploymentClassLoader()));
    final ObjectCloner parameterCloner = createCloner(paramConfig);
    //TODO: this is not very efficient
    final Method method = view.getMethod(invocation.getInvokedMethod().getName(), DescriptorUtils.methodDescriptor(invocation.getInvokedMethod()));
    final boolean async = view.isAsynchronous(method) || invocation.isClientAsync();
    final Object[] parameters;
    if (invocation.getParameters() == null) {
        parameters = EMPTY_OBJECT_ARRAY;
    } else {
        parameters = new Object[invocation.getParameters().length];
        for (int i = 0; i < parameters.length; ++i) {
            parameters[i] = clone(method.getParameterTypes()[i], parameterCloner, invocation.getParameters()[i], allowPassByReference);
        }
    }
    final InterceptorContext interceptorContext = new InterceptorContext();
    interceptorContext.setParameters(parameters);
    interceptorContext.setMethod(method);
    interceptorContext.setTransaction(invocation.getTransaction());
    interceptorContext.setTarget(invocation.getInvokedProxy());
    // setup the context data in the InterceptorContext
    final Map<AttachmentKey<?>, ?> privateAttachments = invocation.getAttachments();
    final Map<String, Object> invocationContextData = invocation.getContextData();
    if (invocationContextData == null && privateAttachments.isEmpty()) {
        // no private or public data
        interceptorContext.setContextData(new HashMap<String, Object>());
    } else {
        final Map<String, Object> data = new HashMap<String, Object>();
        interceptorContext.setContextData(data);
        // write out public (application specific) context data
        if (invocationContextData != null)
            for (Map.Entry<String, Object> entry : invocationContextData.entrySet()) {
                data.put(entry.getKey(), entry.getValue());
            }
        if (!privateAttachments.isEmpty()) {
            // now write out the JBoss specific attachments under a single key and the value will be the
            // entire map of JBoss specific attachments
            data.put(EJBClientInvocationContext.PRIVATE_ATTACHMENTS_KEY, privateAttachments);
        }
        // Note: The code here is just for backward compatibility of 1.0.x version of EJB client project
        // against AS7 7.1.x releases. Discussion here https://github.com/jbossas/jboss-ejb-client/pull/11#issuecomment-6573863
        final boolean txIdAttachmentPresent = privateAttachments.containsKey(AttachmentKeys.TRANSACTION_ID_KEY);
        if (txIdAttachmentPresent) {
            // we additionally add/duplicate the transaction id under a different attachment key
            // to preserve backward compatibility. This is here just for 1.0.x backward compatibility
            data.put(TransactionID.PRIVATE_DATA_KEY, privateAttachments.get(AttachmentKeys.TRANSACTION_ID_KEY));
        }
    }
    interceptorContext.putPrivateData(Component.class, ejbComponent);
    interceptorContext.putPrivateData(ComponentView.class, view);
    if (locator.isStateful()) {
        interceptorContext.putPrivateData(SessionID.class, locator.asStateful().getSessionId());
    } else if (locator instanceof EntityEJBLocator) {
        throw EjbLogger.ROOT_LOGGER.ejbNotFoundInDeployment(locator);
    }
    final ClonerConfiguration config = new ClonerConfiguration();
    config.setClassCloner(new LocalInvocationClassCloner(WildFlySecurityManager.getClassLoaderPrivileged(invocation.getInvokedProxy().getClass())));
    final ObjectCloner resultCloner = createCloner(config);
    if (async) {
        if (ejbComponent instanceof SessionBeanComponent) {
            final CancellationFlag flag = new CancellationFlag();
            final SessionBeanComponent component = (SessionBeanComponent) ejbComponent;
            final boolean isAsync = view.isAsynchronous(method);
            final boolean oneWay = isAsync && method.getReturnType() == void.class;
            final boolean isSessionBean = view.getComponent() instanceof SessionBeanComponent;
            if (isAsync && isSessionBean) {
                if (!oneWay) {
                    interceptorContext.putPrivateData(CancellationFlag.class, flag);
                }
            }
            final SecurityContext securityContext;
            if (WildFlySecurityManager.isChecking()) {
                securityContext = AccessController.doPrivileged((PrivilegedAction<SecurityContext>) SecurityContextAssociation::getSecurityContext);
            } else {
                securityContext = SecurityContextAssociation.getSecurityContext();
            }
            final StartupCountdown.Frame frame = StartupCountdown.current();
            final Runnable task = () -> {
                if (!flag.runIfNotCancelled()) {
                    receiverContext.requestCancelled();
                    return;
                }
                setSecurityContextOnAssociation(securityContext);
                StartupCountdown.restore(frame);
                try {
                    final Object result;
                    try {
                        result = view.invoke(interceptorContext);
                    } catch (Exception e) {
                        // WFLY-4331 - clone the exception of an async task
                        receiverContext.resultReady(new CloningExceptionProducer(invocation, resultCloner, e, allowPassByReference));
                        return;
                    }
                    // if the result is null, there is no cloning needed
                    if (result == null) {
                        receiverContext.resultReady(NULL_RESULT);
                        return;
                    }
                    // WFLY-4331 - clone the result of an async task
                    if (result instanceof Future) {
                        // blocking is very unlikely here, so just defer interrupts when they happen
                        boolean intr = Thread.interrupted();
                        Object asyncValue;
                        try {
                            for (; ; ) try {
                                asyncValue = ((Future<?>) result).get();
                                break;
                            } catch (InterruptedException e) {
                                intr = true;
                            } catch (ExecutionException e) {
                                // WFLY-4331 - clone the exception of an async task
                                receiverContext.resultReady(new CloningExceptionProducer(invocation, resultCloner, e, allowPassByReference));
                                return;
                            }
                        } finally {
                            if (intr)
                                Thread.currentThread().interrupt();
                        }
                        // if the return value is null, there is no cloning needed
                        if (asyncValue == null) {
                            receiverContext.resultReady(NULL_RESULT);
                            return;
                        }
                        receiverContext.resultReady(new CloningResultProducer(invocation, resultCloner, asyncValue, allowPassByReference));
                        return;
                    }
                    receiverContext.resultReady(new CloningResultProducer(invocation, resultCloner, result, allowPassByReference));
                } finally {
                    StartupCountdown.restore(null);
                    clearSecurityContextOnAssociation();
                }
            };
            invocation.putAttachment(CANCELLATION_FLAG_ATTACHMENT_KEY, flag);
            interceptorContext.putPrivateData(CancellationFlag.class, flag);
            final ExecutorService executor = component.getAsynchronousExecutor();
            if (executor == null) {
                receiverContext.resultReady(new EJBReceiverInvocationContext.ResultProducer.Failed(EjbLogger.ROOT_LOGGER.executorIsNull()));
            } else {
                // this normally isn't necessary unless the client didn't detect that it was an async method for some reason
                receiverContext.proceedAsynchronously();
                executor.execute(task);
            }
        } else {
            throw EjbLogger.ROOT_LOGGER.asyncInvocationOnlyApplicableForSessionBeans();
        }
    } else {
        final Object result;
        try {
            result = view.invoke(interceptorContext);
        } catch (Exception e) {
            //we even have to clone the exception type
            //to make sure it matches
            receiverContext.resultReady(new CloningExceptionProducer(invocation, resultCloner, e, allowPassByReference));
            return;
        }
        //we do not marshal the return type unless we have to, the spec only says we have to
        //pass parameters by reference
        receiverContext.resultReady(new CloningResultProducer(invocation, resultCloner, result, allowPassByReference));
    }
}
Also used : HashMap(java.util.HashMap) AttachmentKey(org.jboss.ejb.client.AttachmentKey) PrivilegedAction(java.security.PrivilegedAction) InterceptorContext(org.jboss.invocation.InterceptorContext) ExecutionException(java.util.concurrent.ExecutionException) ObjectCloner(org.jboss.marshalling.cloner.ObjectCloner) StartupCountdown(org.jboss.as.ee.component.deployers.StartupCountdown) EjbDeploymentInformation(org.jboss.as.ejb3.deployment.EjbDeploymentInformation) Method(java.lang.reflect.Method) EJBComponent(org.jboss.as.ejb3.component.EJBComponent) EntityEJBLocator(org.jboss.ejb.client.EntityEJBLocator) SecurityContextAssociation(org.jboss.security.SecurityContextAssociation) ExecutionException(java.util.concurrent.ExecutionException) ComponentView(org.jboss.as.ee.component.ComponentView) SessionBeanComponent(org.jboss.as.ejb3.component.session.SessionBeanComponent) EJBClientInvocationContext(org.jboss.ejb.client.EJBClientInvocationContext) SecurityContext(org.jboss.security.SecurityContext) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) CancellationFlag(org.jboss.as.ejb3.component.interceptors.CancellationFlag) ClassLoaderClassCloner(org.jboss.marshalling.cloner.ClassLoaderClassCloner) ClonerConfiguration(org.jboss.marshalling.cloner.ClonerConfiguration)

Example 5 with InterceptorContext

use of org.jboss.invocation.InterceptorContext in project wildfly by wildfly.

the class ProxyInvocationHandler method invoke.

/** {@inheritDoc} */
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
    final Interceptor interceptor = interceptors.get(method);
    if (interceptor == null) {
        throw new NoSuchMethodError(method.toString());
    }
    final InterceptorContext context = new InterceptorContext();
    // special location for original proxy
    context.putPrivateData(Object.class, proxy);
    context.putPrivateData(Component.class, componentView.getComponent());
    context.putPrivateData(ComponentView.class, componentView);
    instance.prepareInterceptorContext(context);
    context.setParameters(args);
    context.setMethod(method);
    // setup the public context data
    context.setContextData(new HashMap<String, Object>());
    context.setBlockingCaller(true);
    return interceptor.processInvocation(context);
}
Also used : InterceptorContext(org.jboss.invocation.InterceptorContext) Interceptor(org.jboss.invocation.Interceptor)

Aggregations

InterceptorContext (org.jboss.invocation.InterceptorContext)29 Interceptor (org.jboss.invocation.Interceptor)8 Method (java.lang.reflect.Method)4 Component (org.jboss.as.ee.component.Component)4 ComponentView (org.jboss.as.ee.component.ComponentView)4 ManagedReference (org.jboss.as.naming.ManagedReference)4 ComponentConfiguration (org.jboss.as.ee.component.ComponentConfiguration)3 SessionBeanComponent (org.jboss.as.ejb3.component.session.SessionBeanComponent)3 SecurityContext (org.jboss.security.SecurityContext)3 SecurityIdentity (org.wildfly.security.auth.server.SecurityIdentity)3 PrivilegedAction (java.security.PrivilegedAction)2 HashMap (java.util.HashMap)2 ComponentFactory (org.jboss.as.ee.component.ComponentFactory)2 StartupCountdown (org.jboss.as.ee.component.deployers.StartupCountdown)2 InvocationType (org.jboss.as.ee.component.interceptors.InvocationType)2 EJBComponent (org.jboss.as.ejb3.component.EJBComponent)2 CancellationFlag (org.jboss.as.ejb3.component.interceptors.CancellationFlag)2 BAD_OPERATION (org.omg.CORBA.BAD_OPERATION)2 SkeletonStrategy (org.wildfly.iiop.openjdk.rmi.marshal.strategy.SkeletonStrategy)2 ObjectStreamException (java.io.ObjectStreamException)1