+ added fine grained privileged blocks to preserve the caller security stack when invoking the callee
This commit is contained in:
@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
@@ -557,8 +558,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
}
|
||||
final Method readMethod = pd.getReadMethod();
|
||||
try {
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
|
||||
readMethod.setAccessible(true);
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
readMethod.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
readMethod.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
Object value = null;
|
||||
@@ -852,8 +863,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
else {
|
||||
if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
|
||||
final Method readMethod = pd.getReadMethod();
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
|
||||
readMethod.setAccessible(true);
|
||||
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) {
|
||||
if (System.getSecurityManager()!= null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
readMethod.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
readMethod.setAccessible(true);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
@@ -882,8 +903,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
||||
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
|
||||
}
|
||||
final Method writeMethod = pd.getWriteMethod();
|
||||
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
|
||||
writeMethod.setAccessible(true);
|
||||
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
|
||||
if (System.getSecurityManager()!= null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
writeMethod.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
writeMethod.setAccessible(true);
|
||||
}
|
||||
}
|
||||
final Object value = valueToApply;
|
||||
|
||||
|
||||
@@ -1496,8 +1496,15 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
|
||||
}
|
||||
ReflectionUtils.makeAccessible(initMethod);
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
ReflectionUtils.makeAccessible(initMethod);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
|
||||
@@ -1514,6 +1521,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(initMethod);
|
||||
initMethod.invoke(bean, (Object[]) null);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
|
||||
@@ -209,16 +209,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
final String name, final Class<T> requiredType, final Object[] args, final boolean typeCheckOnly)
|
||||
throws BeansException {
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<T>() {
|
||||
public T run() {
|
||||
return doGetBeanRaw(name, requiredType, args, typeCheckOnly);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
return doGetBeanRaw(name, requiredType, args, typeCheckOnly);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return an instance, which may be shared or independent, of the specified bean.
|
||||
@@ -1446,7 +1437,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
@Override
|
||||
protected AccessControlContext getAccessControlContext() {
|
||||
SecurityContextProvider provider = getSecurityContextProvider();
|
||||
return (provider != null ? provider.getAccessControlContext(): null);
|
||||
return (provider != null ? provider.getAccessControlContext(): AccessController.getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -385,8 +385,23 @@ class ConstructorResolver {
|
||||
// Need to determine the factory method...
|
||||
// Try all methods with this name to see if they match the given arguments.
|
||||
factoryClass = ClassUtils.getUserClass(factoryClass);
|
||||
Method[] rawCandidates = (mbd.isNonPublicAccessAllowed() ?
|
||||
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods());
|
||||
Method[] rawCandidates = null;
|
||||
|
||||
final Class factoryClazz = factoryClass;
|
||||
if (System.getSecurityManager() != null) {
|
||||
|
||||
rawCandidates = AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
|
||||
public Method[] run() {
|
||||
return (mbd.isNonPublicAccessAllowed() ?
|
||||
ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods());
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
rawCandidates = (mbd.isNonPublicAccessAllowed() ?
|
||||
ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods());
|
||||
}
|
||||
|
||||
List<Method> candidateSet = new ArrayList<Method>();
|
||||
for (Method candidate : rawCandidates) {
|
||||
if (Modifier.isStatic(candidate.getModifiers()) == isStatic &&
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
@@ -81,7 +82,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
* @param postProcessors the List of BeanPostProcessors
|
||||
* (potentially DestructionAwareBeanPostProcessor), if any
|
||||
*/
|
||||
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
|
||||
public DisposableBeanAdapter(final Object bean, String beanName, RootBeanDefinition beanDefinition,
|
||||
List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
|
||||
|
||||
Assert.notNull(bean, "Bean must not be null");
|
||||
@@ -92,14 +93,26 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.acc = acc;
|
||||
|
||||
String destroyMethodName = beanDefinition.getDestroyMethodName();
|
||||
final String destroyMethodName = beanDefinition.getDestroyMethodName();
|
||||
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
try {
|
||||
this.destroyMethod = (this.nonPublicAccessAllowed ?
|
||||
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
|
||||
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
destroyMethod = (nonPublicAccessAllowed ?
|
||||
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
|
||||
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.destroyMethod = (this.nonPublicAccessAllowed ?
|
||||
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
|
||||
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new BeanDefinitionValidationException("Couldn't find a unique destroy method on bean with name '" +
|
||||
@@ -229,9 +242,15 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
logger.debug("Invoking destroy method '" + this.destroyMethodName +
|
||||
"' on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
ReflectionUtils.makeAccessible(destroyMethod);
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
ReflectionUtils.makeAccessible(destroyMethod);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
public Object run() throws Exception {
|
||||
@@ -244,6 +263,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
||||
}
|
||||
}
|
||||
else {
|
||||
ReflectionUtils.makeAccessible(destroyMethod);
|
||||
destroyMethod.invoke(bean, args);
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
|
||||
@@ -89,9 +89,18 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
||||
|
||||
public Object instantiate(
|
||||
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
|
||||
Constructor ctor, Object[] args) {
|
||||
final Constructor ctor, Object[] args) {
|
||||
|
||||
if (beanDefinition.getMethodOverrides().isEmpty()) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
// use own privileged to change accessibility (when security is on)
|
||||
AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
public Object run() {
|
||||
ReflectionUtils.makeAccessible(ctor);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
return BeanUtils.instantiateClass(ctor, args);
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user