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;
}
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();
}
}
}
}
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);
}
}
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));
}
}
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);
}
Aggregations