/*
* JBoss, Home of Professional Open Source.
* Copyright 2010, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.ejb3.component;
import static java.security.AccessController.doPrivileged;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.Policy;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.TimerService;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagementType;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.security.jacc.EJBRoleRefPermission;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.UserTransaction;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import org.jboss.as.core.security.ServerSecurityManager;
import org.jboss.as.ee.component.BasicComponent;
import org.jboss.as.ee.component.ComponentView;
import org.jboss.as.ejb3.component.allowedmethods.AllowedMethodsInformation;
import org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory;
import org.jboss.as.ejb3.component.invocationmetrics.InvocationMetrics;
import org.jboss.as.ejb3.context.CurrentInvocationContext;
import org.jboss.as.ejb3.logging.EjbLogger;
import org.jboss.as.ejb3.security.EJBSecurityMetaData;
import org.jboss.as.ejb3.security.JaccInterceptor;
import org.jboss.as.ejb3.suspend.EJBSuspendHandlerService;
import org.jboss.as.ejb3.timerservice.TimerServiceImpl;
import org.jboss.as.ejb3.tx.ApplicationExceptionDetails;
import org.jboss.as.naming.ManagedReference;
import org.jboss.as.naming.context.NamespaceContextSelector;
import org.jboss.as.server.CurrentServiceContainer;
import org.jboss.as.server.suspend.ServerActivityCallback;
import org.jboss.ejb.client.Affinity;
import org.jboss.ejb.client.EJBClient;
import org.jboss.ejb.client.EJBHomeLocator;
import org.jboss.invocation.InterceptorContext;
import org.jboss.invocation.InterceptorFactory;
import org.jboss.invocation.proxy.MethodIdentifier;
import org.jboss.msc.service.ServiceContainer;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.wildfly.extension.requestcontroller.ControlPoint;
import org.wildfly.security.auth.server.SecurityDomain;
import org.wildfly.security.auth.server.SecurityIdentity;
import org.wildfly.security.authz.Roles;
import org.wildfly.security.manager.WildFlySecurityManager;
/**
* @author <a href="mailto:cdewolf@redhat.com">Carlo de Wolf</a>
*/
public abstract class EJBComponent extends BasicComponent implements ServerActivityCallback {
private static final ApplicationExceptionDetails APPLICATION_EXCEPTION = new ApplicationExceptionDetails("java.lang.Exception", true, false);
private final Map<MethodTransactionAttributeKey, TransactionAttributeType> txAttrs;
private final Map<MethodTransactionAttributeKey, Integer> txTimeouts;
private final EJBUtilities utilities;
private final boolean isBeanManagedTransaction;
private final Map<Class<?>, ApplicationExceptionDetails> applicationExceptions;
private final EJBSecurityMetaData securityMetaData;
private final Map<String, ServiceName> viewServices;
private final ServiceName ejbLocalHomeViewServiceName;
private final ServiceName ejbHomeViewServiceName;
private final ServiceName ejbObjectViewServiceName;
private final ServiceName ejbLocalObjectViewServiceName;
private final TimerService timerService;
private final Map<Method, InterceptorFactory> timeoutInterceptors;
private final Method timeoutMethod;
private final String applicationName;
private final String earApplicationName;
private final String moduleName;
private final String distinctName;
private final String policyContextID;
private final InvocationMetrics invocationMetrics = new InvocationMetrics();
private final EJBSuspendHandlerService ejbSuspendHandlerService;
private final ShutDownInterceptorFactory shutDownInterceptorFactory;
private final TransactionManager transactionManager;
private final TransactionSynchronizationRegistry transactionSynchronizationRegistry;
private final UserTransaction userTransaction;
private final ServerSecurityManager serverSecurityManager;
private final ControlPoint controlPoint;
private final AtomicBoolean exceptionLoggingEnabled;
private final PrivilegedAction<Principal> getCaller = new PrivilegedAction<Principal>() {
@Override
public Principal run() {
return serverSecurityManager.getCallerPrincipal();
}
};
private final SecurityDomain securityDomain;
private final boolean enableJacc;
private SecurityIdentity incomingRunAsIdentity;
private final Function<SecurityIdentity, Set<SecurityIdentity>> identityOutflowFunction;
private final boolean securityRequired;
/**
* Construct a new instance.
*
* @param ejbComponentCreateService the component configuration
*/
protected EJBComponent(final EJBComponentCreateService ejbComponentCreateService) {
super(ejbComponentCreateService);
this.applicationExceptions = Collections.unmodifiableMap(ejbComponentCreateService.getApplicationExceptions().getApplicationExceptions());
this.utilities = ejbComponentCreateService.getEJBUtilities();
final Map<MethodTransactionAttributeKey, TransactionAttributeType> txAttrs = ejbComponentCreateService.getTxAttrs();
if (txAttrs == null || txAttrs.isEmpty()) {
this.txAttrs = Collections.emptyMap();
} else {
this.txAttrs = txAttrs;
}
final Map<MethodTransactionAttributeKey, Integer> txTimeouts = ejbComponentCreateService.getTxTimeouts();
if (txTimeouts == null || txTimeouts.isEmpty()) {
this.txTimeouts = Collections.emptyMap();
} else {
this.txTimeouts = txTimeouts;
}
isBeanManagedTransaction = TransactionManagementType.BEAN.equals(ejbComponentCreateService.getTransactionManagementType());
// security metadata
this.securityMetaData = ejbComponentCreateService.getSecurityMetaData();
this.viewServices = ejbComponentCreateService.getViewServices();
this.timerService = ejbComponentCreateService.getTimerService();
this.timeoutMethod = ejbComponentCreateService.getTimeoutMethod();
this.ejbLocalHomeViewServiceName = ejbComponentCreateService.getEjbLocalHome();
this.ejbHomeViewServiceName = ejbComponentCreateService.getEjbHome();
this.applicationName = ejbComponentCreateService.getApplicationName();
this.earApplicationName = ejbComponentCreateService.getEarApplicationName();
this.distinctName = ejbComponentCreateService.getDistinctName();
this.policyContextID = ejbComponentCreateService.getPolicyContextID();
this.moduleName = ejbComponentCreateService.getModuleName();
this.ejbObjectViewServiceName = ejbComponentCreateService.getEjbObject();
this.ejbLocalObjectViewServiceName = ejbComponentCreateService.getEjbLocalObject();
this.timeoutInterceptors = Collections.unmodifiableMap(ejbComponentCreateService.getTimeoutInterceptors());
this.shutDownInterceptorFactory = ejbComponentCreateService.getShutDownInterceptorFactory();
this.ejbSuspendHandlerService = ejbComponentCreateService.getEJBSuspendHandler();
this.transactionManager = ejbComponentCreateService.getTransactionManager();
this.transactionSynchronizationRegistry = ejbComponentCreateService.getTransactionSynchronizationRegistry();
this.userTransaction = ejbComponentCreateService.getUserTransaction();
this.serverSecurityManager = ejbComponentCreateService.getServerSecurityManager();
this.controlPoint = ejbComponentCreateService.getControlPoint();
this.exceptionLoggingEnabled = ejbComponentCreateService.getExceptionLoggingEnabled();
this.securityDomain = ejbComponentCreateService.getSecurityDomain();
this.enableJacc = ejbComponentCreateService.isEnableJacc();
this.incomingRunAsIdentity = null;
this.identityOutflowFunction = ejbComponentCreateService.getIdentityOutflowFunction();
this.securityRequired = ejbComponentCreateService.isSecurityRequired();
}
protected <T> T createViewInstanceProxy(final Class<T> viewInterface, final Map<Object, Object> contextData) {
if (viewInterface == null)
throw EjbLogger.ROOT_LOGGER.viewInterfaceCannotBeNull();
if (viewServices.containsKey(viewInterface.getName())) {
final ServiceName serviceName = viewServices.get(viewInterface.getName());
return createViewInstanceProxy(viewInterface, contextData, serviceName);
} else {
throw EjbLogger.ROOT_LOGGER.viewNotFound(viewInterface.getName(), this.getComponentName());
}
}
protected <T> T createViewInstanceProxy(final Class<T> viewInterface, final Map<Object, Object> contextData, final ServiceName serviceName) {
final ServiceController<?> serviceController = currentServiceContainer().getRequiredService(serviceName);
final ComponentView view = (ComponentView) serviceController.getValue();
final ManagedReference instance;
try {
if(WildFlySecurityManager.isChecking()) {
instance = WildFlySecurityManager.doUnchecked(new PrivilegedExceptionAction<ManagedReference>() {
@Override
public ManagedReference run() throws Exception {
return view.createInstance(contextData);
}
});
} else {
instance = view.createInstance(contextData);
}
} catch (Exception e) {
//TODO: do we need to let the exception propagate here?
throw new RuntimeException(e);
}
return viewInterface.cast(instance.getInstance());
}
private static ServiceContainer currentServiceContainer() {
if(System.getSecurityManager() == null) {
return CurrentServiceContainer.getServiceContainer();
}
return AccessController.doPrivileged(CurrentServiceContainer.GET_ACTION);
}
public ApplicationExceptionDetails getApplicationException(Class<?> exceptionClass, Method invokedMethod) {
ApplicationExceptionDetails applicationException = this.applicationExceptions.get(exceptionClass);
if (applicationException != null) {
return applicationException;
}
// Check if the super class of the passed exception class, is an application exception.
Class<?> superClass = exceptionClass.getSuperclass();
while (superClass != null && !(superClass.equals(Exception.class) || superClass.equals(Object.class))) {
applicationException = this.applicationExceptions.get(superClass);
// check whether the "inherited" attribute is set. A subclass of an application exception
// is an application exception only if the inherited attribute on the parent application exception
// is set to true.
if (applicationException != null) {
if (applicationException.isInherited()) {
return applicationException;
}
// Once we find a super class which is an application exception,
// we just stop there (no need to check the grand super class), irrespective of whether the "inherited"
// is true or false
return null; // not an application exception, so return null
}
// move to next super class
superClass = superClass.getSuperclass();
}
// AS7-1317: examine the throws clause of the method
// An unchecked-exception is only an application exception if annotated (or described) as such.
// (see EJB 3.1 FR 14.2.1)
if (RuntimeException.class.isAssignableFrom(exceptionClass) || Error.class.isAssignableFrom(exceptionClass))
return null;
if (invokedMethod != null) {
final Class<?>[] exceptionTypes = invokedMethod.getExceptionTypes();
for (Class<?> type : exceptionTypes) {
if (type.isAssignableFrom(exceptionClass))
return APPLICATION_EXCEPTION;
}
}
// not an application exception, so return null.
return null;
}
public Principal getCallerPrincipal() {
if (isSecurityDomainKnown()) {
return getCallerSecurityIdentity().getPrincipal();
} else if (WildFlySecurityManager.isChecking()) {
return WildFlySecurityManager.doUnchecked(getCaller);
} else {
return this.serverSecurityManager.getCallerPrincipal();
}
}
public SecurityIdentity getIncomingRunAsIdentity() {
return incomingRunAsIdentity;
}
public void setIncomingRunAsIdentity(SecurityIdentity identity) {
this.incomingRunAsIdentity = identity;
}
protected TransactionAttributeType getCurrentTransactionAttribute() {
final InterceptorContext invocation = CurrentInvocationContext.get();
final MethodIntf methodIntf = MethodIntfHelper.of(invocation);
return getTransactionAttributeType(methodIntf, invocation.getMethod());
}
public EJBHome getEJBHome() throws IllegalStateException {
if (ejbHomeViewServiceName == null) {
throw EjbLogger.ROOT_LOGGER.beanHomeInterfaceIsNull(getComponentName());
}
final ServiceController<?> serviceController = currentServiceContainer().getRequiredService(ejbHomeViewServiceName);
final ComponentView view = (ComponentView) serviceController.getValue();
final String locatorAppName = earApplicationName == null ? "" : earApplicationName;
return EJBClient.createProxy(createHomeLocator(view.getViewClass().asSubclass(EJBHome.class), locatorAppName, moduleName, getComponentName(), distinctName));
}
private static <T extends EJBHome> EJBHomeLocator<T> createHomeLocator(Class<T> viewClass, String appName, String moduleName, String beanName, String distinctName) {
return new EJBHomeLocator<T>(viewClass, appName, moduleName, beanName, distinctName, Affinity.LOCAL);
}
public Class<?> getEjbObjectType() {
if (ejbObjectViewServiceName == null) {
return null;
}
final ServiceController<?> serviceController = currentServiceContainer().getRequiredService(ejbObjectViewServiceName);
final ComponentView view = (ComponentView) serviceController.getValue();
return view.getViewClass();
}
public Class<?> getEjbLocalObjectType() {
if (ejbLocalObjectViewServiceName == null) {
return null;
}
final ServiceController<?> serviceController = currentServiceContainer().getRequiredService(ejbLocalObjectViewServiceName);
final ComponentView view = (ComponentView) serviceController.getValue();
return view.getViewClass();
}
public EJBLocalHome getEJBLocalHome() throws IllegalStateException {
if (ejbLocalHomeViewServiceName == null) {
throw EjbLogger.ROOT_LOGGER.beanLocalHomeInterfaceIsNull(getComponentName());
}
return createViewInstanceProxy(EJBLocalHome.class, Collections.emptyMap(), ejbLocalHomeViewServiceName);
}
public boolean getRollbackOnly() throws IllegalStateException {
if (isBeanManagedTransaction()) {
throw EjbLogger.ROOT_LOGGER.failToCallgetRollbackOnly();
}
try {
TransactionManager tm = this.getTransactionManager();
// The getRollbackOnly method should be used only in the context of a transaction.
if (tm.getTransaction() == null) {
throw EjbLogger.ROOT_LOGGER.failToCallgetRollbackOnlyOnNoneTransaction();
}
// EJBTHREE-805, consider an asynchronous rollback due to timeout
// This is counter to EJB 3.1 where an asynchronous call does not inherit the transaction context!
int status = tm.getStatus();
EjbLogger.ROOT_LOGGER.tracef("Current transaction status is %d", status);
switch (status) {
case Status.STATUS_COMMITTED:
case Status.STATUS_ROLLEDBACK:
throw EjbLogger.ROOT_LOGGER.failToCallgetRollbackOnlyAfterTxcompleted();
case Status.STATUS_MARKED_ROLLBACK:
case Status.STATUS_ROLLING_BACK:
return true;
}
return false;
} catch (SystemException se) {
EjbLogger.ROOT_LOGGER.getTxManagerStatusFailed(se);
return true;
}
}
public ServerSecurityManager getSecurityManager() {
return this.serverSecurityManager;
}
public TimerService getTimerService() throws IllegalStateException {
return timerService;
}
public TransactionAttributeType getTransactionAttributeType(final MethodIntf methodIntf, final Method method) {
return getTransactionAttributeType(methodIntf, MethodIdentifier.getIdentifierForMethod(method));
}
public TransactionAttributeType getTransactionAttributeType(final MethodIntf methodIntf, final MethodIdentifier method) {
return getTransactionAttributeType(methodIntf, method, TransactionAttributeType.REQUIRED);
}
public TransactionAttributeType getTransactionAttributeType(final MethodIntf methodIntf, final MethodIdentifier method, TransactionAttributeType defaultType) {
TransactionAttributeType txAttr = txAttrs.get(new MethodTransactionAttributeKey(methodIntf, method));
//fall back to type bean if not found
if (txAttr == null && methodIntf != MethodIntf.BEAN) {
txAttr = txAttrs.get(new MethodTransactionAttributeKey(MethodIntf.BEAN, method));
}
if (txAttr == null)
return defaultType;
return txAttr;
}
public TransactionManager getTransactionManager() {
return this.transactionManager;
}
public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() {
return this.transactionSynchronizationRegistry;
}
public int getTransactionTimeout(final MethodIntf methodIntf, final Method method) {
return getTransactionTimeout(methodIntf, MethodIdentifier.getIdentifierForMethod(method));
}
public int getTransactionTimeout(final MethodIntf methodIntf, final MethodIdentifier method) {
Integer txTimeout = txTimeouts.get(new MethodTransactionAttributeKey(methodIntf, method));
if (txTimeout == null && methodIntf != MethodIntf.BEAN) {
txTimeout = txTimeouts.get(new MethodTransactionAttributeKey(MethodIntf.BEAN, method));
}
if (txTimeout == null)
return -1;
return txTimeout;
}
public UserTransaction getUserTransaction() throws IllegalStateException {
return this.userTransaction;
}
public boolean isBeanManagedTransaction() {
return isBeanManagedTransaction;
}
public boolean isCallerInRole(final String roleName) throws IllegalStateException {
if (isSecurityDomainKnown()) {
if (enableJacc) {
Policy policy = WildFlySecurityManager.isChecking() ? doPrivileged((PrivilegedAction<Policy>) Policy::getPolicy) : Policy.getPolicy();
ProtectionDomain domain = new ProtectionDomain(null, null, null, JaccInterceptor.getGrantedRoles(getCallerSecurityIdentity()));
return policy.implies(domain, new EJBRoleRefPermission(getComponentName(), roleName));
} else {
return checkCallerSecurityIdentityRole(roleName);
}
} else if (WildFlySecurityManager.isChecking()) {
return WildFlySecurityManager.doUnchecked((PrivilegedAction<Boolean>) () -> serverSecurityManager.isCallerInRole(getComponentName(), policyContextID, securityMetaData.getSecurityRoles(), securityMetaData.getSecurityRoleLinks(), roleName));
} else {
return this.serverSecurityManager.isCallerInRole(getComponentName(), policyContextID, securityMetaData.getSecurityRoles(), securityMetaData.getSecurityRoleLinks(), roleName);
}
}
public boolean isStatisticsEnabled() {
return utilities.isStatisticsEnabled();
}
public Object lookup(String name) throws IllegalArgumentException {
if (name == null) {
throw EjbLogger.ROOT_LOGGER.jndiNameCannotBeNull();
}
final NamespaceContextSelector namespaceContextSelector = NamespaceContextSelector.getCurrentSelector();
if (namespaceContextSelector == null) {
throw EjbLogger.ROOT_LOGGER.noNamespaceContextSelectorAvailable(name);
}
Context jndiContext = null;
String namespaceStrippedJndiName = name;
// get the appropriate JNDI context and strip the lookup jndi name of the component namespace prefix
if (name.startsWith("java:app/")) {
jndiContext = namespaceContextSelector.getContext("app");
namespaceStrippedJndiName = name.substring("java:app/".length());
} else if (name.startsWith("java:module/")) {
jndiContext = namespaceContextSelector.getContext("module");
namespaceStrippedJndiName = name.substring("java:module/".length());
} else if (name.startsWith("java:comp/")) {
jndiContext = namespaceContextSelector.getContext("comp");
namespaceStrippedJndiName = name.substring("java:comp/".length());
} else if (!name.startsWith("java:")) { // if it *doesn't* start with java: prefix, then default it to java:comp
jndiContext = namespaceContextSelector.getContext("comp");
// no need to strip the name since it doesn't start with java: prefix.
// Also prefix the "env/" to the jndi name, since a lookup without a java: namespace prefix is effectively
// a lookup under java:comp/env/<jndi-name>
namespaceStrippedJndiName = "env/" + name;
} else if (name.startsWith("java:global/")) {
// Do *not* strip the jndi name of the prefix because java:global is a global context and doesn't specifically
// belong to the component's ENC, and hence *isn't* a component ENC relative name and has to be looked up
// with the absolute name (including the java:global prefix)
try {
jndiContext = new InitialContext();
} catch (NamingException ne) {
throw EjbLogger.ROOT_LOGGER.failToLookupJNDI(name, ne);
}
} else {
throw EjbLogger.ROOT_LOGGER.failToLookupJNDINameSpace(name);
}
EjbLogger.ROOT_LOGGER.debugf("Looking up %s in jndi context: %s", namespaceStrippedJndiName, jndiContext);
try {
return jndiContext.lookup(namespaceStrippedJndiName);
} catch (NamingException ne) {
throw EjbLogger.ROOT_LOGGER.failToLookupStrippedJNDI(namespaceContextSelector, jndiContext, ne);
}
}
public void setRollbackOnly() throws IllegalStateException {
if (isBeanManagedTransaction()) {
throw EjbLogger.ROOT_LOGGER.failToCallSetRollbackOnlyOnNoneCMB();
}
try {
// get the transaction manager
TransactionManager tm = getTransactionManager();
// check if there's a tx in progress. If not, then it's an error to call setRollbackOnly()
if (tm.getTransaction() == null) {
throw EjbLogger.ROOT_LOGGER.failToCallSetRollbackOnlyWithNoTx();
}
// set rollback
tm.setRollbackOnly();
} catch (SystemException se) {
EjbLogger.ROOT_LOGGER.setRollbackOnlyFailed(se);
}
}
public EJBSecurityMetaData getSecurityMetaData() {
return this.securityMetaData;
}
public Method getTimeoutMethod() {
return timeoutMethod;
}
public String getApplicationName() {
return applicationName;
}
public String getEarApplicationName() {
return this.earApplicationName;
}
public String getDistinctName() {
return distinctName;
}
public String getModuleName() {
return moduleName;
}
public ServiceName getEjbLocalObjectViewServiceName() {
return ejbLocalObjectViewServiceName;
}
public ServiceName getEjbLocalHomeViewServiceName() {
return ejbLocalHomeViewServiceName;
}
public ServiceName getEjbHomeViewServiceName() {
return ejbHomeViewServiceName;
}
public ServiceName getEjbObjectViewServiceName() {
return ejbObjectViewServiceName;
}
public Map<Method, InterceptorFactory> getTimeoutInterceptors() {
return timeoutInterceptors;
}
public AllowedMethodsInformation getAllowedMethodsInformation() {
return isBeanManagedTransaction() ? AllowedMethodsInformation.INSTANCE_BMT : AllowedMethodsInformation.INSTANCE_CMT;
}
public InvocationMetrics getInvocationMetrics() {
return invocationMetrics;
}
public ControlPoint getControlPoint() {
return this.controlPoint;
}
public SecurityDomain getSecurityDomain() {
return securityDomain;
}
public boolean isSecurityDomainKnown() {
return securityDomain != null;
}
public Function<SecurityIdentity, Set<SecurityIdentity>> getIdentityOutflowFunction() {
return identityOutflowFunction;
}
@Override
public synchronized void start() {
getShutDownInterceptorFactory().start();
super.start();
if(this.timerService instanceof TimerServiceImpl) {
((TimerServiceImpl) this.timerService).activate();
}
}
@Override
public final void stop() {
getShutDownInterceptorFactory().shutdown();
if(this.timerService instanceof TimerServiceImpl) {
((TimerServiceImpl) this.timerService).deactivate();
}
this.done();
}
@Override
public void done() {
super.stop();
}
public boolean isExceptionLoggingEnabled() {
return exceptionLoggingEnabled.get();
}
protected ShutDownInterceptorFactory getShutDownInterceptorFactory() {
return shutDownInterceptorFactory;
}
private boolean checkCallerSecurityIdentityRole(String roleName) {
final SecurityIdentity identity = getCallerSecurityIdentity();
if("**".equals(roleName)) {
return !identity.isAnonymous();
}
Roles roles = identity.getRoles("ejb", true);
if(roles.contains(roleName)) {
return true;
}
if(securityMetaData.getSecurityRoleLinks() != null) {
Collection<String> linked = securityMetaData.getSecurityRoleLinks().get(roleName);
if(linked != null) {
for (String role : roles) {
if (linked.contains(role)) {
return true;
}
}
}
}
return false;
}
private SecurityIdentity getCallerSecurityIdentity() {
if (incomingRunAsIdentity != null) {
return incomingRunAsIdentity;
} else if (securityRequired) {
return securityDomain.getCurrentSecurityIdentity();
} else {
// unsecured EJB
return securityDomain.getAnonymousSecurityIdentity();
}
}
public EJBSuspendHandlerService getEjbSuspendHandlerService() {
return this.ejbSuspendHandlerService;
}
}