Search in sources :

Example 1 with InterceptorFactory

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

the class EJBSecurityViewConfigurator method configure.

@Override
public void configure(DeploymentPhaseContext context, ComponentConfiguration componentConfiguration, ViewDescription viewDescription, ViewConfiguration viewConfiguration) throws DeploymentUnitProcessingException {
    if (componentConfiguration.getComponentDescription() instanceof EJBComponentDescription == false) {
        throw EjbLogger.ROOT_LOGGER.invalidEjbComponent(componentConfiguration.getComponentName(), componentConfiguration.getComponentClass());
    }
    final DeploymentUnit deploymentUnit = context.getDeploymentUnit();
    final EJBComponentDescription ejbComponentDescription = (EJBComponentDescription) componentConfiguration.getComponentDescription();
    final boolean elytronSecurityDomain = ejbComponentDescription.getSecurityDomainServiceName() != null;
    final String viewClassName = viewDescription.getViewClassName();
    final EJBViewDescription ejbViewDescription = (EJBViewDescription) viewDescription;
    final EJBViewMethodSecurityAttributesService.Builder viewMethodSecurityAttributesServiceBuilder;
    final ServiceName viewMethodSecurityAttributesServiceName;
    // note that we always install this service for SERVICE_ENDPOINT views, even if security is not enabled
    if (MethodIntf.SERVICE_ENDPOINT == ejbViewDescription.getMethodIntf()) {
        viewMethodSecurityAttributesServiceBuilder = new EJBViewMethodSecurityAttributesService.Builder();
        viewMethodSecurityAttributesServiceName = EJBViewMethodSecurityAttributesService.getServiceName(ejbComponentDescription.getApplicationName(), ejbComponentDescription.getModuleName(), ejbComponentDescription.getEJBName(), viewClassName);
    } else {
        viewMethodSecurityAttributesServiceBuilder = null;
        viewMethodSecurityAttributesServiceName = null;
    }
    if (!legacySecurityAvailable(deploymentUnit) && !elytronSecurityDomain) {
        // the security subsystem is not present and Elytron is not being used for security, we don't apply any security settings
        installAttributeServiceIfRequired(context, viewMethodSecurityAttributesServiceBuilder, viewMethodSecurityAttributesServiceName);
        return;
    }
    final DeploymentReflectionIndex deploymentReflectionIndex = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.REFLECTION_INDEX);
    // The getSecurityDomain() will return a null value if neither an explicit security domain is configured
    // for the bean nor there's any default security domain that's configured at EJB3 subsystem level.
    // In such cases, we do *not* apply any security interceptors
    String resolvedSecurityDomain = ejbComponentDescription.getResolvedSecurityDomain();
    if (elytronSecurityDomain == false && (resolvedSecurityDomain == null || resolvedSecurityDomain.isEmpty())) {
        if (ROOT_LOGGER.isDebugEnabled()) {
            ROOT_LOGGER.debug("Security is *not* enabled on EJB: " + ejbComponentDescription.getEJBName() + ", since no explicit security domain is configured for the bean, nor is there any default security domain configured in the EJB3 subsystem");
        }
        installAttributeServiceIfRequired(context, viewMethodSecurityAttributesServiceBuilder, viewMethodSecurityAttributesServiceName);
        return;
    }
    // setup the JACC contextID.
    String contextID = deploymentUnit.getName();
    if (deploymentUnit.getParent() != null) {
        contextID = deploymentUnit.getParent().getName() + "!" + contextID;
    }
    // setup the method specific security interceptor(s)
    boolean beanHasMethodLevelSecurityMetadata = false;
    final List<Method> viewMethods = viewConfiguration.getProxyFactory().getCachedMethods();
    final List<Method> methodsWithoutExplicitSecurityConfiguration = new ArrayList<Method>();
    for (final Method viewMethod : viewMethods) {
        // TODO: proxy factory exposes non-public methods, is this a bug in the no-interface view?
        if (!Modifier.isPublic(viewMethod.getModifiers())) {
            continue;
        }
        if (viewMethod.getDeclaringClass() == WriteReplaceInterface.class) {
            continue;
        }
        // setup the authorization interceptor
        final ApplicableMethodInformation<EJBMethodSecurityAttribute> permissions = ejbComponentDescription.getDescriptorMethodPermissions();
        boolean methodHasSecurityMetadata = handlePermissions(contextID, componentConfiguration, viewConfiguration, deploymentReflectionIndex, viewClassName, ejbViewDescription, viewMethod, permissions, false, viewMethodSecurityAttributesServiceBuilder, ejbComponentDescription, elytronSecurityDomain, resolvedSecurityDomain);
        if (!methodHasSecurityMetadata) {
            // if it was not handled by the descriptor processor we look for annotation basic info
            methodHasSecurityMetadata = handlePermissions(contextID, componentConfiguration, viewConfiguration, deploymentReflectionIndex, viewClassName, ejbViewDescription, viewMethod, ejbComponentDescription.getAnnotationMethodPermissions(), true, viewMethodSecurityAttributesServiceBuilder, ejbComponentDescription, elytronSecurityDomain, resolvedSecurityDomain);
        }
        // if any method has security metadata then the bean has method level security metadata
        if (methodHasSecurityMetadata) {
            beanHasMethodLevelSecurityMetadata = true;
        } else {
            // make a note that this method didn't have any explicit method permissions configured
            methodsWithoutExplicitSecurityConfiguration.add(viewMethod);
        }
    }
    final boolean securityRequired = beanHasMethodLevelSecurityMetadata || ejbComponentDescription.hasBeanLevelSecurityMetadata();
    if (securityRequired) {
        ejbComponentDescription.setSecurityRequired(securityRequired);
    }
    // setup the security context interceptor
    if (elytronSecurityDomain) {
        final HashMap<Integer, InterceptorFactory> elytronInterceptorFactories = ejbComponentDescription.getElytronInterceptorFactories(contextID, ejbComponentDescription.requiresJacc(), true);
        elytronInterceptorFactories.forEach((priority, elytronInterceptorFactory) -> viewConfiguration.addViewInterceptor(elytronInterceptorFactory, priority));
    } else if (securityRequired) {
        throw ROOT_LOGGER.legacySecurityUnsupported(resolvedSecurityDomain);
    }
    // now add the authorization interceptor if the bean has *any* security metadata applicable
    if (securityRequired) {
        // check the missing-method-permissions-deny-access configuration and add the authorization interceptor
        // to methods which don't have explicit method permissions.
        // (@see http://anil-identity.blogspot.in/2010/02/tip-interpretation-of-missing-ejb.html for details)
        final Boolean denyAccessToMethodsMissingPermissions = ((EJBComponentDescription) componentConfiguration.getComponentDescription()).isMissingMethodPermissionsDeniedAccess();
        // default to "deny access"
        if (denyAccessToMethodsMissingPermissions != Boolean.FALSE) {
            for (final Method viewMethod : methodsWithoutExplicitSecurityConfiguration) {
                if (viewMethodSecurityAttributesServiceBuilder != null) {
                    // build the EJBViewMethodSecurityAttributesService to expose these security attributes to other components like WS (@see https://issues.jboss.org/browse/WFLY-308)
                    viewMethodSecurityAttributesServiceBuilder.addMethodSecurityMetadata(viewMethod, EJBMethodSecurityAttribute.denyAll());
                }
                // "deny access" implies we need the authorization interceptor to be added so that it can nuke the invocation
                if (elytronSecurityDomain) {
                    viewConfiguration.addViewInterceptor(viewMethod, new ImmediateInterceptorFactory(RolesAllowedInterceptor.DENY_ALL), InterceptorOrder.View.EJB_SECURITY_AUTHORIZATION_INTERCEPTOR);
                } else {
                    throw ROOT_LOGGER.legacySecurityUnsupported(resolvedSecurityDomain);
                }
            }
        }
    }
    installAttributeServiceIfRequired(context, viewMethodSecurityAttributesServiceBuilder, viewMethodSecurityAttributesServiceName);
}
Also used : EJBViewDescription(org.jboss.as.ejb3.component.EJBViewDescription) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) EJBComponentDescription(org.jboss.as.ejb3.component.EJBComponentDescription) EJBViewMethodSecurityAttributesService(org.jboss.as.ejb3.security.service.EJBViewMethodSecurityAttributesService) InterceptorFactory(org.jboss.invocation.InterceptorFactory) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) ServiceName(org.jboss.msc.service.ServiceName) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) DeploymentUnit(org.jboss.as.server.deployment.DeploymentUnit) DeploymentReflectionIndex(org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex)

Example 2 with InterceptorFactory

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

the class ServerInterceptorCache method findAnnotatedMethods.

private List<InterceptorFactory> findAnnotatedMethods(final Class<?> interceptorClass, final Index index, final Class<?> annotationClass) {
    final List<InterceptorFactory> interceptorFactories = new ArrayList<>();
    final DotName annotationName = DotName.createSimple(annotationClass.getName());
    final List<AnnotationInstance> annotations = index.getAnnotations(annotationName);
    for (final AnnotationInstance annotation : annotations) {
        if (annotation.target().kind() == AnnotationTarget.Kind.METHOD) {
            final MethodInfo methodInfo = annotation.target().asMethod();
            final Constructor<?> constructor;
            try {
                constructor = interceptorClass.getConstructor();
            } catch (NoSuchMethodException e) {
                throw EjbLogger.ROOT_LOGGER.serverInterceptorNoEmptyConstructor(interceptorClass.toString(), e);
            }
            try {
                final Method annotatedMethod = interceptorClass.getMethod(methodInfo.name(), new Class[] { InvocationContext.class });
                final InterceptorFactory interceptorFactory = createInterceptorFactoryForServerInterceptor(annotatedMethod, constructor);
                interceptorFactories.add(interceptorFactory);
            } catch (NoSuchMethodException e) {
                throw EjbLogger.ROOT_LOGGER.serverInterceptorInvalidMethod(methodInfo.name(), interceptorClass.toString(), annotationClass.toString(), e);
            }
        }
    }
    return interceptorFactories;
}
Also used : InterceptorFactory(org.jboss.invocation.InterceptorFactory) ContainerInterceptorMethodInterceptorFactory(org.jboss.as.ejb3.component.ContainerInterceptorMethodInterceptorFactory) ArrayList(java.util.ArrayList) MethodInfo(org.jboss.jandex.MethodInfo) Method(java.lang.reflect.Method) DotName(org.jboss.jandex.DotName) AnnotationInstance(org.jboss.jandex.AnnotationInstance)

Example 3 with InterceptorFactory

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

the class BasicComponent method createInterceptors.

protected void createInterceptors(InterceptorFactoryContext context) {
    // Create the post-construct interceptors for the ComponentInstance
    postConstructInterceptor = this.postConstruct.create(context);
    // create the pre-destroy interceptors
    preDestroyInterceptor = this.getPreDestroy().create(context);
    final Map<Method, InterceptorFactory> interceptorFactoryMap = this.getInterceptorFactoryMap();
    // This is an identity map.  This means that only <b>certain</b> {@code Method} objects will
    // match - specifically, they must equal the objects provided to the proxy.
    final IdentityHashMap<Method, Interceptor> interceptorMap = new IdentityHashMap<Method, Interceptor>();
    for (Method method : interceptorFactoryMap.keySet()) {
        interceptorMap.put(method, interceptorFactoryMap.get(method).create(context));
    }
    this.interceptorInstanceMap = interceptorMap;
}
Also used : InterceptorFactory(org.jboss.invocation.InterceptorFactory) IdentityHashMap(java.util.IdentityHashMap) Method(java.lang.reflect.Method) Interceptor(org.jboss.invocation.Interceptor)

Example 4 with InterceptorFactory

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

the class ComponentConfiguration method addTimeoutViewInterceptor.

/**
 * Adds a timeout interceptor factory to every method on the component.
 *
 * @param factory  The interceptor factory to add
 * @param priority The interceptors relative order
 */
public void addTimeoutViewInterceptor(InterceptorFactory factory, int priority) {
    for (Method method : (Iterable<Method>) classIndex.getClassMethods()) {
        OrderedItemContainer<InterceptorFactory> interceptors = timeoutInterceptors.get(method);
        if (interceptors == null) {
            timeoutInterceptors.put(method, interceptors = new OrderedItemContainer<InterceptorFactory>());
        }
        interceptors.add(factory, priority);
    }
}
Also used : InterceptorFactory(org.jboss.invocation.InterceptorFactory) OrderedItemContainer(org.jboss.as.ee.component.interceptors.OrderedItemContainer) Method(java.lang.reflect.Method)

Example 5 with InterceptorFactory

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

the class EJBComponentDescription method getElytronInterceptorFactories.

public HashMap<Integer, InterceptorFactory> getElytronInterceptorFactories(String policyContextID, boolean enableJacc, boolean propagateSecurity) {
    final HashMap<Integer, InterceptorFactory> interceptorFactories = new HashMap<>(2);
    final Set<String> roles = new HashSet<>();
    // First interceptor: security domain association
    interceptorFactories.put(InterceptorOrder.View.SECURITY_CONTEXT, SecurityDomainInterceptorFactory.INSTANCE);
    if (enableJacc) {
        // Next interceptor: policy context ID
        interceptorFactories.put(InterceptorOrder.View.POLICY_CONTEXT, new ImmediateInterceptorFactory(new PolicyContextIdInterceptor(policyContextID)));
    }
    if (securityRoles != null) {
        final Map<String, Set<String>> principalVsRolesMap = securityRoles.getPrincipalVersusRolesMap();
        if (!principalVsRolesMap.isEmpty()) {
            interceptorFactories.put(InterceptorOrder.View.SECURITY_ROLES, new ImmediateInterceptorFactory(new SecurityRolesAddingInterceptor("ejb", principalVsRolesMap)));
        }
    }
    // Switch users if there's a run-as principal
    if (runAsPrincipal != null) {
        interceptorFactories.put(InterceptorOrder.View.RUN_AS_PRINCIPAL, new ImmediateInterceptorFactory(new RunAsPrincipalInterceptor(runAsPrincipal)));
        // Next interceptor: extra principal roles
        if (securityRoles != null) {
            final Set<String> extraRoles = securityRoles.getSecurityRoleNamesByPrincipal(runAsPrincipal);
            if (!extraRoles.isEmpty()) {
                interceptorFactories.put(InterceptorOrder.View.EXTRA_PRINCIPAL_ROLES, new ImmediateInterceptorFactory(new RoleAddingInterceptor("ejb", RoleMapper.constant(Roles.fromSet(extraRoles)))));
                roles.addAll(extraRoles);
            }
        }
    // Next interceptor: prevent identity propagation
    } else if (!propagateSecurity) {
        interceptorFactories.put(InterceptorOrder.View.RUN_AS_PRINCIPAL, new ImmediateInterceptorFactory(new RunAsPrincipalInterceptor(RunAsPrincipalInterceptor.ANONYMOUS_PRINCIPAL)));
    }
    // Next interceptor: run-as-role
    if (runAsRole != null) {
        interceptorFactories.put(InterceptorOrder.View.RUN_AS_ROLE, new ImmediateInterceptorFactory(new RoleAddingInterceptor("ejb", RoleMapper.constant(Roles.fromSet(Collections.singleton(runAsRole))))));
        roles.add(runAsRole);
    }
    // Next interceptor: security identity outflow
    if (!roles.isEmpty()) {
        interceptorFactories.put(InterceptorOrder.View.SECURITY_IDENTITY_OUTFLOW, new IdentityOutflowInterceptorFactory("ejb", RoleMapper.constant(Roles.fromSet(roles))));
    } else {
        interceptorFactories.put(InterceptorOrder.View.SECURITY_IDENTITY_OUTFLOW, IdentityOutflowInterceptorFactory.INSTANCE);
    }
    // Ignoring declared roles
    RoleMapper.constant(Roles.fromSet(getDeclaredRoles()));
    return interceptorFactories;
}
Also used : IdentityOutflowInterceptorFactory(org.jboss.as.ejb3.security.IdentityOutflowInterceptorFactory) Set(java.util.Set) HashSet(java.util.HashSet) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) PolicyContextIdInterceptor(org.jboss.as.ejb3.security.PolicyContextIdInterceptor) RoleAddingInterceptor(org.jboss.as.ejb3.security.RoleAddingInterceptor) IdentityOutflowInterceptorFactory(org.jboss.as.ejb3.security.IdentityOutflowInterceptorFactory) InterceptorFactory(org.jboss.invocation.InterceptorFactory) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) SecurityDomainInterceptorFactory(org.jboss.as.ejb3.security.SecurityDomainInterceptorFactory) ShutDownInterceptorFactory(org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory) ImmediateInterceptorFactory(org.jboss.invocation.ImmediateInterceptorFactory) RunAsPrincipalInterceptor(org.jboss.as.ejb3.security.RunAsPrincipalInterceptor) HashSet(java.util.HashSet) SecurityRolesAddingInterceptor(org.jboss.as.ejb3.security.SecurityRolesAddingInterceptor)

Aggregations

InterceptorFactory (org.jboss.invocation.InterceptorFactory)15 Method (java.lang.reflect.Method)12 ArrayList (java.util.ArrayList)7 ImmediateInterceptorFactory (org.jboss.invocation.ImmediateInterceptorFactory)7 HashMap (java.util.HashMap)5 DeploymentUnit (org.jboss.as.server.deployment.DeploymentUnit)5 List (java.util.List)4 UserInterceptorFactory (org.jboss.as.ee.component.interceptors.UserInterceptorFactory)4 DeploymentReflectionIndex (org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex)4 ComponentDescription (org.jboss.as.ee.component.ComponentDescription)3 InterceptorClassDescription (org.jboss.as.ee.component.interceptors.InterceptorClassDescription)3 DeploymentUnitProcessingException (org.jboss.as.server.deployment.DeploymentUnitProcessingException)3 Interceptor (org.jboss.invocation.Interceptor)3 MethodIdentifier (org.jboss.invocation.proxy.MethodIdentifier)3 Module (org.jboss.modules.Module)3 ServiceName (org.jboss.msc.service.ServiceName)3 ArrayDeque (java.util.ArrayDeque)2 IdentityHashMap (java.util.IdentityHashMap)2 ComponentConfiguration (org.jboss.as.ee.component.ComponentConfiguration)2 ComponentConfigurator (org.jboss.as.ee.component.ComponentConfigurator)2