Skip to content

Commit

Permalink
Merge pull request wildfly#6453 from sguilhen/master
Browse files Browse the repository at this point in the history
Fix for connector and timer TCK regressions
  • Loading branch information
kabir committed Jun 28, 2014
2 parents c9b8292 + 458ad9d commit 86e3c98
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,14 @@ public interface ServerSecurityManager {

Subject getSubject();

//TODO: we have no internal users of this, find out if it is used downstream
@Deprecated
boolean isCallerInRole(final String ejbName, final Object mappedRoles, final Map<String, Collection<String>> roleLinks,
final String... roleNames);

boolean isCallerInRole(final String ejbName, String policyContextId, final Object mappedRoles, final Map<String, Collection<String>> roleLinks,
final String... roleNames);

boolean authorize(String ejbName, CodeSource ejbCodeSource, String ejbMethodIntf, Method ejbMethod, Set<Principal> methodRoles, String contextID);

}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public abstract class EJBComponent extends BasicComponent {
private final String earApplicationName;
private final String moduleName;
private final String distinctName;
private final String policyContextID;
private final EJBRemoteTransactionsRepository ejbRemoteTransactionsRepository;

private final InvocationMetrics invocationMetrics = new InvocationMetrics();
Expand Down Expand Up @@ -149,6 +150,7 @@ protected EJBComponent(final EJBComponentCreateService ejbComponentCreateService
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();
Expand Down Expand Up @@ -396,11 +398,11 @@ public boolean isCallerInRole(final String roleName) throws IllegalStateExceptio
if (WildFlySecurityManager.isChecking()) {
return WildFlySecurityManager.doUnchecked(new PrivilegedAction<Boolean>() {
public Boolean run() {
return serverSecurityManager.isCallerInRole(getComponentName(), securityMetaData.getSecurityRoles(), securityMetaData.getSecurityRoleLinks(), roleName);
return serverSecurityManager.isCallerInRole(getComponentName(), policyContextID, securityMetaData.getSecurityRoles(), securityMetaData.getSecurityRoleLinks(), roleName);
}
});
} else {
return this.serverSecurityManager.isCallerInRole(getComponentName(), securityMetaData.getSecurityRoles(), securityMetaData.getSecurityRoleLinks(), roleName);
return this.serverSecurityManager.isCallerInRole(getComponentName(), policyContextID, securityMetaData.getSecurityRoles(), securityMetaData.getSecurityRoleLinks(), roleName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public class EJBComponentCreateService extends BasicComponentCreateService {
private final String earApplicationName;
private final String moduleName;
private final String distinctName;
private final String policyContextID;

private final ShutDownInterceptorFactory shutDownInterceptorFactory;

Expand All @@ -110,6 +111,7 @@ public EJBComponentCreateService(final ComponentConfiguration componentConfigura
this.transactionManagementType = ejbComponentDescription.getTransactionManagementType();

this.timerService = ejbComponentDescription.getTimerService();
this.policyContextID = ejbComponentDescription.getPolicyContextID();

// CMTTx
if (transactionManagementType.equals(TransactionManagementType.CONTAINER)) {
Expand Down Expand Up @@ -346,4 +348,7 @@ Injector<ServerSecurityManager> getServerSecurityManagerInjector() {
return this.serverSecurityManagerInjectedValue;
}

public String getPolicyContextID() {
return this.policyContextID;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ public abstract class EJBComponentDescription extends ComponentDescription {
*/
private Boolean missingMethodPermissionsDenyAccess = null;

private String policyContextID;

/**
* Construct a new instance.
*
Expand Down Expand Up @@ -296,6 +298,7 @@ public EJBComponentDescription(final String componentName, final String componen
@Override
public void configure(final DeploymentPhaseContext context, final ComponentDescription description, final ComponentConfiguration configuration) throws DeploymentUnitProcessingException {

policyContextID = SecurityContextInterceptorFactory.contextIdForDeployment(context.getDeploymentUnit());
//make sure java:comp/env is always available, even if nothing is bound there
if (description.getNamingMode() == ComponentNamingMode.CREATE) {
description.getBindingConfigurations().add(new BindingConfiguration("java:comp/env", new ContextInjectionSource("env", "java:comp/env")));
Expand All @@ -314,7 +317,7 @@ public void configure(final DeploymentPhaseContext context, final ComponentDescr
configuration.addTimeoutViewInterceptor(new ImmediateInterceptorFactory(new ContextClassLoaderInterceptor(classLoader)), InterceptorOrder.View.TCCL_INTERCEPTOR);
configuration.addTimeoutViewInterceptor(configuration.getNamespaceContextInterceptorFactory(), InterceptorOrder.View.JNDI_NAMESPACE_INTERCEPTOR);
configuration.addTimeoutViewInterceptor(CurrentInvocationContextInterceptor.FACTORY, InterceptorOrder.View.INVOCATION_CONTEXT_INTERCEPTOR);
configuration.addTimeoutViewInterceptor(new SecurityContextInterceptorFactory(hasBeanLevelSecurityMetadata()), InterceptorOrder.View.SECURITY_CONTEXT);
configuration.addTimeoutViewInterceptor(new SecurityContextInterceptorFactory(hasBeanLevelSecurityMetadata(), policyContextID), InterceptorOrder.View.SECURITY_CONTEXT);
for (final Method method : configuration.getClassIndex().getClassMethods()) {
configuration.addTimeoutViewInterceptor(method, new ImmediateInterceptorFactory(new ComponentDispatcherInterceptor(method)), InterceptorOrder.View.COMPONENT_DISPATCHER);
}
Expand Down Expand Up @@ -1019,6 +1022,14 @@ public Set<InterceptorDescription> getAllContainerInterceptors() {
return this.allContainerInterceptors;
}

public String getPolicyContextID() {
return policyContextID;
}

public void setPolicyContextID(String policyContextID) {
this.policyContextID = policyContextID;
}

@Override
public String toString() {
return getClass().getName() + "{" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ public ComponentConfiguration createConfiguration(final ClassIndex classIndex, f
getConfigurators().add(new ComponentConfigurator() {
@Override
public void configure(final DeploymentPhaseContext context, final ComponentDescription description, final ComponentConfiguration configuration) throws DeploymentUnitProcessingException {
configuration.addPostConstructInterceptor(new SecurityContextInterceptorFactory(isExplicitSecurityDomainConfigured(), false), InterceptorOrder.View.SECURITY_CONTEXT);
configuration.addPostConstructInterceptor(new SecurityContextInterceptorFactory(isExplicitSecurityDomainConfigured(), false,
SecurityContextInterceptorFactory.contextIdForDeployment(context.getDeploymentUnit())), InterceptorOrder.View.SECURITY_CONTEXT);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import org.jboss.as.ejb3.deployment.ApplicableMethodInformation;
import org.jboss.as.ejb3.security.service.EJBViewMethodSecurityAttributesService;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.reflect.ClassReflectionIndexUtil;
import org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex;
Expand Down Expand Up @@ -80,11 +79,7 @@ public void configure(DeploymentPhaseContext context, ComponentConfiguration com
final EJBViewDescription ejbViewDescription = (EJBViewDescription) viewDescription;

// setup the JACC contextID.
DeploymentUnit deploymentUnit = context.getDeploymentUnit();
String contextID = deploymentUnit.getName();
if (deploymentUnit.getParent() != null) {
contextID = deploymentUnit.getParent().getName() + "!" + contextID;
}
String contextID = SecurityContextInterceptorFactory.contextIdForDeployment(context.getDeploymentUnit());

final EJBViewMethodSecurityAttributesService.Builder viewMethodSecurityAttributesServiceBuilder;
final ServiceName viewMethodSecurityAttributesServiceName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.jboss.as.ejb3.logging.EjbLogger;
import org.jboss.as.ejb3.component.EJBComponent;
import org.jboss.as.security.service.SimpleSecurityManager;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.invocation.Interceptor;
import org.jboss.invocation.InterceptorFactoryContext;
import org.jboss.metadata.javaee.spec.SecurityRolesMetaData;
Expand All @@ -47,8 +48,16 @@ public class SecurityContextInterceptorFactory extends ComponentInterceptorFacto
private final boolean propagateSecurity;
private final String policyContextID;

public SecurityContextInterceptorFactory(final boolean securityRequired) {
this(securityRequired, true);
public static String contextIdForDeployment(final DeploymentUnit du) {
String contextID = du.getName();
if (du.getParent() != null) {
contextID = du.getParent().getName() + "!" + contextID;
}
return contextID;
}

public SecurityContextInterceptorFactory(final boolean securityRequired, final String policyContextID) {
this(securityRequired, true, policyContextID);
}

public SecurityContextInterceptorFactory(final boolean securityRequired, final boolean propagateSecurity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.jboss.as.security.logging.SecurityLogger;
import org.jboss.as.security.remoting.RemotingConnectionCredential;
import org.jboss.as.security.remoting.RemotingConnectionPrincipal;
import org.jboss.metadata.javaee.spec.SecurityRolesMetaData;
import org.jboss.remoting3.Connection;
import org.jboss.remoting3.security.UserInfo;
import org.jboss.security.AuthenticationManager;
Expand All @@ -56,6 +57,7 @@
import org.jboss.security.SecurityContextAssociation;
import org.jboss.security.SecurityContextFactory;
import org.jboss.security.SecurityContextUtil;
import org.jboss.security.SecurityRolesAssociation;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.SubjectInfo;
import org.jboss.security.audit.AuditEvent;
Expand Down Expand Up @@ -176,6 +178,11 @@ private Principal getPrincipal(Subject subject) {
return callerPrincipal == null ? principal : callerPrincipal;
}

@Override
public boolean isCallerInRole(String ejbName, Object mappedRoles, Map<String, Collection<String>> roleLinks, String... roleNames) {
return isCallerInRole(ejbName, PolicyContext.getContextID(), mappedRoles, roleLinks, roleNames);
}

/**
* @param ejbName The name of the EJB component where isCallerInRole was invoked.
* @param incommingMappedRoles The principal vs roles mapping (if any). Can be null.
Expand All @@ -184,7 +191,7 @@ private Principal getPrincipal(Subject subject) {
* @param roleNames The role names for which the caller is being checked for
* @return true if the user is in <b>any</b> one of the <code>roleNames</code>. Else returns false
*/
public boolean isCallerInRole(final String ejbName, final Object incommingMappedRoles,
public boolean isCallerInRole(final String ejbName, final String policyContextID, final Object incommingMappedRoles,
final Map<String, Collection<String>> roleLinks, final String... roleNames) {

final SecurityContext securityContext = doPrivileged(securityContext());
Expand All @@ -194,7 +201,7 @@ public boolean isCallerInRole(final String ejbName, final Object incommingMapped

final EJBResource resource = new EJBResource(new HashMap<String, Object>());
resource.setEjbName(ejbName);
resource.setPolicyContextID(PolicyContext.getContextID());
resource.setPolicyContextID(policyContextID);
resource.setCallerRunAsIdentity(securityContext.getIncomingRunAs());
resource.setCallerSubject(securityContext.getUtil().getSubject());
Principal userPrincipal = securityContext.getUtil().getUserPrincipal();
Expand All @@ -211,7 +218,14 @@ public boolean isCallerInRole(final String ejbName, final Object incommingMapped
resource.setSecurityRoleReferences(roleRefs);
}

Map<String, Set<String>> previousRolesAssociationMap = null;
try {
// ensure the security roles association contains the incoming principal x roles map.
if (incommingMappedRoles != null) {
SecurityRolesMetaData rolesMetaData = (SecurityRolesMetaData) incommingMappedRoles;
previousRolesAssociationMap = this.setSecurityRolesAssociation(rolesMetaData.getPrincipalVersusRolesMap());
}

AbstractEJBAuthorizationHelper helper = SecurityHelperFactory.getEJBAuthorizationHelper(securityContext);
for (String roleName : roleNames) {
if (helper.isCallerInRole(resource, roleName)) {
Expand All @@ -223,6 +237,12 @@ public boolean isCallerInRole(final String ejbName, final Object incommingMapped
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
// reset the security roles association state.
if (incommingMappedRoles != null) {
this.setSecurityRolesAssociation(previousRolesAssociationMap);
}
}
}

public boolean authorize(String ejbName, CodeSource ejbCodeSource, String ejbMethodIntf, Method ejbMethod, Set<Principal> methodRoles, String contextID) {
Expand Down Expand Up @@ -448,4 +468,32 @@ public RoleGroup run() {
}
});
}

private Map<String, Set<String>> setSecurityRolesAssociation(Map<String, Set<String>> mappedRoles) {
if (System.getSecurityManager() == null) {
Map<String, Set<String>> previousMappedRoles = SecurityRolesAssociation.getSecurityRoles();
SecurityRolesAssociation.setSecurityRoles(mappedRoles);
return previousMappedRoles;
}
else {
SetSecurityRolesAssociationAction action = new SetSecurityRolesAssociationAction(mappedRoles);
return AccessController.doPrivileged(action);
}
}

private static class SetSecurityRolesAssociationAction implements PrivilegedAction<Map<String, Set<String>>> {

private final Map<String, Set<String>> mappedRoles;

SetSecurityRolesAssociationAction(Map<String, Set<String>> mappedRoles) {
this.mappedRoles = mappedRoles;
}

@Override
public Map<String, Set<String>> run() {
Map<String, Set<String>> previousMappedRoles = SecurityRolesAssociation.getSecurityRoles();
SecurityRolesAssociation.setSecurityRoles(this.mappedRoles);
return previousMappedRoles;
}
}
}

0 comments on commit 86e3c98

Please sign in to comment.