Search in sources :

Example 6 with SecurityContext

use of org.jboss.security.SecurityContext 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 7 with SecurityContext

use of org.jboss.security.SecurityContext in project wildfly by wildfly.

the class ConnectionSecurityContext method pushIdentity.

/**
     * Push a new {@link Principal} and Credential pair.
     *
     * This method is to be called before an EJB invocation is passed through it's security interceptor, at that point the
     * Principal and Credential pair can be verified.
     *
     * Note: This method should be called from within a {@link PrivilegedAction}.
     *
     * @param principal - The alternative {@link Principal} to use in verification before the next EJB is called.
     * @param credential - The credential to verify with the {@linl Principal}
     * @return A {@link ContextStateCache} that can later be used to pop the identity pushed here and restore internal state to it's previous values.
     * @throws Exception If there is a problem associating the new {@link Principal} and Credential pair.
     */
public static ContextStateCache pushIdentity(final Principal principal, final Object credential) throws Exception {
    SecurityContext current = SecurityContextAssociation.getSecurityContext();
    SecurityContext nextContext = SecurityContextFactory.createSecurityContext(principal, credential, new Subject(), "USER_DELEGATION");
    SecurityContextAssociation.setSecurityContext(nextContext);
    Connection con = RemotingContext.getConnection();
    RemotingContext.clear();
    return new ContextStateCache(con, current);
}
Also used : SecurityContext(org.jboss.security.SecurityContext) Connection(org.jboss.remoting3.Connection) Subject(javax.security.auth.Subject)

Example 8 with SecurityContext

use of org.jboss.security.SecurityContext in project wildfly by wildfly.

the class SimpleSecurityManager method push.

/**
     * Must be called from within a privileged action.
     *
     * @param securityDomain
     */
public void push(final String securityDomain) {
    // TODO - Handle a null securityDomain here? Yes I think so.
    final SecurityContext previous = SecurityContextAssociation.getSecurityContext();
    contexts.push(previous);
    SecurityContext current = establishSecurityContext(securityDomain);
    if (propagate && previous != null) {
        current.setSubjectInfo(getSubjectInfo(previous));
        current.setIncomingRunAs(previous.getOutgoingRunAs());
    }
    RunAs currentRunAs = current.getIncomingRunAs();
    boolean trusted = currentRunAs != null && currentRunAs instanceof RunAsIdentity;
    if (trusted == false) {
        /*
             * We should only be switching to a context based on an identity from the Remoting connection if we don't already
             * have a trusted identity - this allows for beans to reauthenticate as a different identity.
             */
        if (SecurityActions.remotingContextIsSet()) {
            // In this case the principal and credential will not have been set to set some random values.
            SecurityContextUtil util = current.getUtil();
            Connection connection = SecurityActions.remotingContextGetConnection();
            Principal p = null;
            Object credential = null;
            SecurityIdentity localIdentity = connection.getLocalIdentity();
            if (localIdentity != null) {
                p = new SimplePrincipal(localIdentity.getPrincipal().getName());
                IdentityCredentials privateCredentials = localIdentity.getPrivateCredentials();
                PasswordCredential passwordCredential = privateCredentials.getCredential(PasswordCredential.class, ClearPassword.ALGORITHM_CLEAR);
                if (passwordCredential != null) {
                    credential = new String(passwordCredential.getPassword(ClearPassword.class).getPassword());
                } else {
                    credential = new RemotingConnectionCredential(connection);
                }
            } else {
                throw SecurityLogger.ROOT_LOGGER.noUserPrincipalFound();
            }
            SecurityActions.remotingContextClear();
            util.createSubjectInfo(p, credential, null);
        }
    }
}
Also used : ClearPassword(org.wildfly.security.password.interfaces.ClearPassword) SecurityContextUtil(org.jboss.security.SecurityContextUtil) RunAs(org.jboss.security.RunAs) RunAsIdentity(org.jboss.security.RunAsIdentity) Connection(org.jboss.remoting3.Connection) PasswordCredential(org.wildfly.security.credential.PasswordCredential) SecurityIdentity(org.wildfly.security.auth.server.SecurityIdentity) SecurityContext(org.jboss.security.SecurityContext) RemotingConnectionCredential(org.jboss.as.security.remoting.RemotingConnectionCredential) Principal(java.security.Principal) SimplePrincipal(org.jboss.security.SimplePrincipal) SimplePrincipal(org.jboss.security.SimplePrincipal) IdentityCredentials(org.wildfly.security.auth.server.IdentityCredentials)

Example 9 with SecurityContext

use of org.jboss.security.SecurityContext in project wildfly by wildfly.

the class SimpleSecurityManager method authorize.

public boolean authorize(String ejbName, CodeSource ejbCodeSource, String ejbMethodIntf, Method ejbMethod, Set<Principal> methodRoles, String contextID) {
    final SecurityContext securityContext = doPrivileged(securityContext());
    if (securityContext == null) {
        return false;
    }
    EJBResource resource = new EJBResource(new HashMap<String, Object>());
    resource.setEjbName(ejbName);
    resource.setEjbMethod(ejbMethod);
    resource.setEjbMethodInterface(ejbMethodIntf);
    resource.setEjbMethodRoles(new SimpleRoleGroup(methodRoles));
    resource.setCodeSource(ejbCodeSource);
    resource.setPolicyContextID(contextID);
    resource.setCallerRunAsIdentity(securityContext.getIncomingRunAs());
    resource.setCallerSubject(securityContext.getUtil().getSubject());
    Principal userPrincipal = securityContext.getUtil().getUserPrincipal();
    resource.setPrincipal(userPrincipal);
    try {
        AbstractEJBAuthorizationHelper helper = SecurityHelperFactory.getEJBAuthorizationHelper(securityContext);
        return helper.authorize(resource);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : EJBResource(org.jboss.security.authorization.resources.EJBResource) AbstractEJBAuthorizationHelper(org.jboss.security.javaee.AbstractEJBAuthorizationHelper) SecurityContext(org.jboss.security.SecurityContext) Principal(java.security.Principal) SimplePrincipal(org.jboss.security.SimplePrincipal) SimpleRoleGroup(org.jboss.security.identity.plugins.SimpleRoleGroup)

Example 10 with SecurityContext

use of org.jboss.security.SecurityContext in project wildfly by wildfly.

the class SimpleSecurityManager method getCallerPrincipal.

public Principal getCallerPrincipal() {
    final SecurityContext securityContext = doPrivileged(securityContext());
    if (securityContext == null) {
        return getUnauthenticatedIdentity().asPrincipal();
    }
    /*
         * final Principal principal = getPrincipal(securityContext.getUtil().getSubject());
         */
    Principal principal = securityContext.getIncomingRunAs();
    if (principal == null)
        principal = getPrincipal(getSubjectInfo(securityContext).getAuthenticatedSubject());
    if (principal == null)
        return getUnauthenticatedIdentity().asPrincipal();
    return principal;
}
Also used : SecurityContext(org.jboss.security.SecurityContext) Principal(java.security.Principal) SimplePrincipal(org.jboss.security.SimplePrincipal)

Aggregations

SecurityContext (org.jboss.security.SecurityContext)26 Subject (javax.security.auth.Subject)10 Principal (java.security.Principal)9 SimplePrincipal (org.jboss.security.SimplePrincipal)7 RunAs (org.jboss.security.RunAs)5 RunAsIdentity (org.jboss.security.RunAsIdentity)5 Connection (org.jboss.remoting3.Connection)4 SecurityIdentity (org.wildfly.security.auth.server.SecurityIdentity)4 IOException (java.io.IOException)3 PrivilegedAction (java.security.PrivilegedAction)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 InterceptorContext (org.jboss.invocation.InterceptorContext)3 Set (java.util.Set)2 StartupCountdown (org.jboss.as.ee.component.deployers.StartupCountdown)2 SessionBeanComponent (org.jboss.as.ejb3.component.session.SessionBeanComponent)2 RemotingConnectionCredential (org.jboss.as.security.remoting.RemotingConnectionCredential)2 SecurityContextUtil (org.jboss.security.SecurityContextUtil)2 EJBResource (org.jboss.security.authorization.resources.EJBResource)2