Remove support for deprecated Java SecurityManager (-> JDK 17 build compatibility)
Includes hard JDK 9+ API dependency in CGLIB ReflectUtils (Lookup.defineClass) and removal of OutputStream spy proxy usage (avoiding invalid Mockito proxy on JDK 17) Closes gh-26901
This commit is contained in:
parent
0640da74bc
commit
cf2429b0f0
|
|
@ -23,7 +23,8 @@ sourceSets {
|
|||
}
|
||||
|
||||
compileGroovy {
|
||||
options.compilerArgs += "-Werror"
|
||||
// Groovy generates Java code with "new Boolean" usage which is deprecated on JDK 17
|
||||
// options.compilerArgs += "-Werror"
|
||||
}
|
||||
|
||||
// This module also builds Kotlin code and the compileKotlin task naturally depends on
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -18,11 +18,6 @@ package org.springframework.beans;
|
|||
|
||||
import java.beans.PropertyDescriptor;
|
||||
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 org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.Property;
|
||||
|
|
@ -69,12 +64,6 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
|||
@Nullable
|
||||
private CachedIntrospectionResults cachedIntrospectionResults;
|
||||
|
||||
/**
|
||||
* The security context used for invoking the property methods.
|
||||
*/
|
||||
@Nullable
|
||||
private AccessControlContext acc;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
|
||||
|
|
@ -131,7 +120,6 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
|||
*/
|
||||
private BeanWrapperImpl(Object object, String nestedPath, BeanWrapperImpl parent) {
|
||||
super(object, nestedPath, parent);
|
||||
setSecurityContext(parent.acc);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -176,23 +164,6 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
|||
return this.cachedIntrospectionResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security context used during the invocation of the wrapped instance methods.
|
||||
* Can be null.
|
||||
*/
|
||||
public void setSecurityContext(@Nullable AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the security context used during the invocation of the wrapped instance methods.
|
||||
* Can be null.
|
||||
*/
|
||||
@Nullable
|
||||
public AccessControlContext getSecurityContext() {
|
||||
return this.acc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert the given value for the specified property to the latter's type.
|
||||
|
|
@ -290,23 +261,8 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
|||
@Nullable
|
||||
public Object getValue() throws Exception {
|
||||
Method readMethod = this.pd.getReadMethod();
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
ReflectionUtils.makeAccessible(readMethod);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
|
||||
() -> readMethod.invoke(getWrappedInstance(), (Object[]) null), acc);
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ReflectionUtils.makeAccessible(readMethod);
|
||||
return readMethod.invoke(getWrappedInstance(), (Object[]) null);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(readMethod);
|
||||
return readMethod.invoke(getWrappedInstance(), (Object[]) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -314,23 +270,8 @@ public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements
|
|||
Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
|
||||
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
|
||||
this.pd.getWriteMethod());
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
ReflectionUtils.makeAccessible(writeMethod);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
|
||||
() -> writeMethod.invoke(getWrappedInstance(), value), acc);
|
||||
}
|
||||
catch (PrivilegedActionException ex) {
|
||||
throw ex.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ReflectionUtils.makeAccessible(writeMethod);
|
||||
writeMethod.invoke(getWrappedInstance(), value);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(writeMethod);
|
||||
writeMethod.invoke(getWrappedInstance(), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.security.AccessControlContext;
|
||||
|
||||
import org.springframework.beans.PropertyEditorRegistrar;
|
||||
import org.springframework.beans.PropertyEditorRegistry;
|
||||
|
|
@ -291,13 +290,6 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
|
|||
*/
|
||||
ApplicationStartup getApplicationStartup();
|
||||
|
||||
/**
|
||||
* Provides a security access control context relevant to this factory.
|
||||
* @return the applicable AccessControlContext (never {@code null})
|
||||
* @since 3.0
|
||||
*/
|
||||
AccessControlContext getAccessControlContext();
|
||||
|
||||
/**
|
||||
* Copy all relevant configuration from the given other factory.
|
||||
* <p>Should include all standard configuration settings as well as
|
||||
|
|
|
|||
|
|
@ -21,10 +21,6 @@ import java.lang.reflect.Constructor;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -387,15 +383,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
|
||||
}
|
||||
else {
|
||||
Object bean;
|
||||
if (System.getSecurityManager() != null) {
|
||||
bean = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(bd, null, this),
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
bean = getInstantiationStrategy().instantiate(bd, null, this);
|
||||
}
|
||||
Object bean = getInstantiationStrategy().instantiate(bd, null, this);
|
||||
populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
|
||||
return bean;
|
||||
}
|
||||
|
|
@ -463,8 +451,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
|
||||
@Override
|
||||
public void destroyBean(Object existingBean) {
|
||||
new DisposableBeanAdapter(
|
||||
existingBean, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();
|
||||
new DisposableBeanAdapter(existingBean, getBeanPostProcessorCache().destructionAware).destroy();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1316,15 +1303,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
*/
|
||||
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
|
||||
try {
|
||||
Object beanInstance;
|
||||
if (System.getSecurityManager() != null) {
|
||||
beanInstance = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
|
||||
}
|
||||
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
|
||||
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
|
||||
initBeanWrapper(bw);
|
||||
return bw;
|
||||
|
|
@ -1655,10 +1634,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
return;
|
||||
}
|
||||
|
||||
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
|
||||
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
|
||||
}
|
||||
|
||||
MutablePropertyValues mpvs = null;
|
||||
List<PropertyValue> original;
|
||||
|
||||
|
|
@ -1781,15 +1756,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
* @see #applyBeanPostProcessorsAfterInitialization
|
||||
*/
|
||||
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
invokeAwareMethods(beanName, bean);
|
||||
return null;
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
invokeAwareMethods(beanName, bean);
|
||||
}
|
||||
invokeAwareMethods(beanName, bean);
|
||||
|
||||
Object wrappedBean = bean;
|
||||
if (mbd == null || !mbd.isSynthetic()) {
|
||||
|
|
@ -1848,20 +1815,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
|
||||
}
|
||||
if (System.getSecurityManager() != null) {
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||
((InitializingBean) bean).afterPropertiesSet();
|
||||
return null;
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
((InitializingBean) bean).afterPropertiesSet();
|
||||
}
|
||||
((InitializingBean) bean).afterPropertiesSet();
|
||||
}
|
||||
|
||||
if (mbd != null && bean.getClass() != NullBean.class) {
|
||||
|
|
@ -1910,28 +1864,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
}
|
||||
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
ReflectionUtils.makeAccessible(methodToInvoke);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
|
||||
() -> methodToInvoke.invoke(bean), getAccessControlContext());
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
InvocationTargetException ex = (InvocationTargetException) pae.getException();
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(methodToInvoke);
|
||||
methodToInvoke.invoke(bean);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
ReflectionUtils.makeAccessible(methodToInvoke);
|
||||
methodToInvoke.invoke(bean);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,11 +17,6 @@
|
|||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -166,10 +161,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
/** Map from scope identifier String to corresponding Scope. */
|
||||
private final Map<String, Scope> scopes = new LinkedHashMap<>(8);
|
||||
|
||||
/** Security context used when running with a SecurityManager. */
|
||||
@Nullable
|
||||
private SecurityContextProvider securityContextProvider;
|
||||
|
||||
/** Map from bean name to merged RootBeanDefinition. */
|
||||
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
|
||||
|
||||
|
|
@ -495,17 +486,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
}
|
||||
if (isFactoryBean(beanName, mbd)) {
|
||||
FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<Boolean>) () ->
|
||||
((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) ||
|
||||
!fb.isSingleton()),
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) ||
|
||||
!fb.isSingleton());
|
||||
}
|
||||
return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) ||
|
||||
!fb.isSingleton());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
|
@ -1054,15 +1036,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
return this.scopes.get(scopeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the security context provider for this bean factory. If a security manager
|
||||
* is set, interaction with the user code will be executed using the privileged
|
||||
* of the provided security context.
|
||||
*/
|
||||
public void setSecurityContextProvider(SecurityContextProvider securityProvider) {
|
||||
this.securityContextProvider = securityProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationStartup(ApplicationStartup applicationStartup) {
|
||||
Assert.notNull(applicationStartup, "applicationStartup should not be null");
|
||||
|
|
@ -1074,17 +1047,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
return this.applicationStartup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate the creation of the access control context to the
|
||||
* {@link #setSecurityContextProvider SecurityContextProvider}.
|
||||
*/
|
||||
@Override
|
||||
public AccessControlContext getAccessControlContext() {
|
||||
return (this.securityContextProvider != null ?
|
||||
this.securityContextProvider.getAccessControlContext() :
|
||||
AccessController.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
|
||||
Assert.notNull(otherFactory, "BeanFactory must not be null");
|
||||
|
|
@ -1099,7 +1061,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
this.typeConverter = otherAbstractFactory.typeConverter;
|
||||
this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
|
||||
this.scopes.putAll(otherAbstractFactory.scopes);
|
||||
this.securityContextProvider = otherAbstractFactory.securityContextProvider;
|
||||
}
|
||||
else {
|
||||
setTypeConverter(otherFactory.getTypeConverter());
|
||||
|
|
@ -1222,7 +1183,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
*/
|
||||
protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
|
||||
new DisposableBeanAdapter(
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware).destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1526,17 +1487,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
if (mbd.hasBeanClass()) {
|
||||
return mbd.getBeanClass();
|
||||
}
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
|
||||
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return doResolveBeanClass(mbd, typesToMatch);
|
||||
}
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
|
||||
return doResolveBeanClass(mbd, typesToMatch);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
|
||||
|
|
@ -1925,14 +1876,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
* @see #registerDependentBean
|
||||
*/
|
||||
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
|
||||
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
|
||||
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
|
||||
if (mbd.isSingleton()) {
|
||||
// Register a DisposableBean implementation that performs all destruction
|
||||
// work for the given bean: DestructionAwareBeanPostProcessors,
|
||||
// DisposableBean interface, custom destroy method.
|
||||
registerDisposableBean(beanName, new DisposableBeanAdapter(
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware));
|
||||
}
|
||||
else {
|
||||
// A bean with a custom scope...
|
||||
|
|
@ -1941,7 +1891,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
|
||||
}
|
||||
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
|
||||
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ import java.lang.reflect.Constructor;
|
|||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -302,14 +300,7 @@ class ConstructorResolver {
|
|||
|
||||
try {
|
||||
InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
|
||||
strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),
|
||||
this.beanFactory.getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
|
||||
}
|
||||
return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
|
|
@ -365,15 +356,8 @@ class ConstructorResolver {
|
|||
* Called as the starting point for factory method determination.
|
||||
*/
|
||||
private Method[] getCandidateMethods(Class<?> factoryClass, RootBeanDefinition mbd) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<Method[]>) () ->
|
||||
(mbd.isNonPublicAccessAllowed() ?
|
||||
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods()));
|
||||
}
|
||||
else {
|
||||
return (mbd.isNonPublicAccessAllowed() ?
|
||||
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods());
|
||||
}
|
||||
return (mbd.isNonPublicAccessAllowed() ?
|
||||
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -643,16 +627,8 @@ class ConstructorResolver {
|
|||
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {
|
||||
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
|
||||
this.beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),
|
||||
this.beanFactory.getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return this.beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
|
||||
}
|
||||
return this.beanFactory.getInstantiationStrategy().instantiate(
|
||||
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -25,8 +25,6 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -296,15 +294,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
public void setAutowireCandidateResolver(AutowireCandidateResolver autowireCandidateResolver) {
|
||||
Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
|
||||
if (autowireCandidateResolver instanceof BeanFactoryAware) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
|
||||
return null;
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
|
||||
}
|
||||
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
|
||||
}
|
||||
this.autowireCandidateResolver = autowireCandidateResolver;
|
||||
}
|
||||
|
|
@ -925,16 +915,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
|
||||
if (bean instanceof FactoryBean) {
|
||||
FactoryBean<?> factory = (FactoryBean<?>) bean;
|
||||
boolean isEagerInit;
|
||||
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
|
||||
isEagerInit = AccessController.doPrivileged(
|
||||
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
|
||||
getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
isEagerInit = (factory instanceof SmartFactoryBean &&
|
||||
((SmartFactoryBean<?>) factory).isEagerInit());
|
||||
}
|
||||
boolean isEagerInit = (factory instanceof SmartFactoryBean &&
|
||||
((SmartFactoryBean<?>) factory).isEagerInit());
|
||||
if (isEagerInit) {
|
||||
getBean(beanName);
|
||||
}
|
||||
|
|
@ -953,15 +935,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
|
||||
.tag("beanName", beanName);
|
||||
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
smartSingleton.afterSingletonsInstantiated();
|
||||
return null;
|
||||
}, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
smartSingleton.afterSingletonsInstantiated();
|
||||
}
|
||||
smartSingleton.afterSingletonsInstantiated();
|
||||
smartInitialize.end();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@ package org.springframework.beans.factory.support;
|
|||
import java.io.Serializable;
|
||||
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;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -76,9 +71,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
|
||||
private final boolean nonPublicAccessAllowed;
|
||||
|
||||
@Nullable
|
||||
private final AccessControlContext acc;
|
||||
|
||||
@Nullable
|
||||
private String destroyMethodName;
|
||||
|
||||
|
|
@ -98,7 +90,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
* (potentially DestructionAwareBeanPostProcessor), if any
|
||||
*/
|
||||
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
|
||||
List<DestructionAwareBeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
|
||||
List<DestructionAwareBeanPostProcessor> postProcessors) {
|
||||
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
|
|
@ -106,7 +98,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
this.invokeDisposableBean =
|
||||
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
|
||||
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
|
||||
this.acc = acc;
|
||||
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
|
||||
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
|
||||
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
|
||||
|
|
@ -143,15 +134,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
* @param postProcessors the List of BeanPostProcessors
|
||||
* (potentially DestructionAwareBeanPostProcessor), if any
|
||||
*/
|
||||
public DisposableBeanAdapter(
|
||||
Object bean, List<DestructionAwareBeanPostProcessor> postProcessors, AccessControlContext acc) {
|
||||
|
||||
public DisposableBeanAdapter(Object bean, List<DestructionAwareBeanPostProcessor> postProcessors) {
|
||||
Assert.notNull(bean, "Disposable bean must not be null");
|
||||
this.bean = bean;
|
||||
this.beanName = bean.getClass().getName();
|
||||
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
|
||||
this.nonPublicAccessAllowed = true;
|
||||
this.acc = acc;
|
||||
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +154,6 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
this.beanName = beanName;
|
||||
this.invokeDisposableBean = invokeDisposableBean;
|
||||
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
|
||||
this.acc = null;
|
||||
this.destroyMethodName = destroyMethodName;
|
||||
this.beanPostProcessors = postProcessors;
|
||||
}
|
||||
|
|
@ -190,15 +177,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||
((DisposableBean) this.bean).destroy();
|
||||
return null;
|
||||
}, this.acc);
|
||||
}
|
||||
else {
|
||||
((DisposableBean) this.bean).destroy();
|
||||
}
|
||||
((DisposableBean) this.bean).destroy();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
|
||||
|
|
@ -226,12 +205,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
@Nullable
|
||||
private Method determineDestroyMethod(String name) {
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged((PrivilegedAction<Method>) () -> findDestroyMethod(name));
|
||||
}
|
||||
else {
|
||||
return findDestroyMethod(name);
|
||||
}
|
||||
return findDestroyMethod(name);
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new BeanDefinitionValidationException("Could not find unique destroy method on bean with name '" +
|
||||
|
|
@ -263,23 +237,8 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
|
|||
"' on bean with name '" + this.beanName + "'");
|
||||
}
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
ReflectionUtils.makeAccessible(destroyMethod);
|
||||
return null;
|
||||
});
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
|
||||
destroyMethod.invoke(this.bean, args), this.acc);
|
||||
}
|
||||
catch (PrivilegedActionException pax) {
|
||||
throw (InvocationTargetException) pax.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ReflectionUtils.makeAccessible(destroyMethod);
|
||||
destroyMethod.invoke(this.bean, args);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(destroyMethod);
|
||||
destroyMethod.invoke(this.bean, args);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" +
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -16,11 +16,6 @@
|
|||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
|
@ -56,13 +51,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
|||
@Nullable
|
||||
protected Class<?> getTypeForFactoryBean(FactoryBean<?> factoryBean) {
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
return AccessController.doPrivileged(
|
||||
(PrivilegedAction<Class<?>>) factoryBean::getObjectType, getAccessControlContext());
|
||||
}
|
||||
else {
|
||||
return factoryBean.getObjectType();
|
||||
}
|
||||
return factoryBean.getObjectType();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// Thrown from the FactoryBean's getObjectType implementation.
|
||||
|
|
@ -156,18 +145,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
|||
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
|
||||
Object object;
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessControlContext acc = getAccessControlContext();
|
||||
try {
|
||||
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
|
||||
}
|
||||
catch (PrivilegedActionException pae) {
|
||||
throw pae.getException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
object = factory.getObject();
|
||||
}
|
||||
object = factory.getObject();
|
||||
}
|
||||
catch (FactoryBeanNotInitializedException ex) {
|
||||
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
|
||||
|
|
@ -239,14 +217,4 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the security context for this bean factory. If a security manager
|
||||
* is set, interaction with the user code will be executed using the privileged
|
||||
* of the security context returned by this method.
|
||||
* @see AccessController#getContext()
|
||||
*/
|
||||
protected AccessControlContext getAccessControlContext() {
|
||||
return AccessController.getContext();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
|
||||
/**
|
||||
* Provider of the security context of the code running inside the bean factory.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface SecurityContextProvider {
|
||||
|
||||
/**
|
||||
* Provides a security access control context relevant to a bean factory.
|
||||
* @return bean factory security control context
|
||||
*/
|
||||
AccessControlContext getAccessControlContext();
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -19,9 +19,6 @@ package org.springframework.beans.factory.support;
|
|||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
|
@ -70,13 +67,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
|||
throw new BeanInstantiationException(clazz, "Specified class is an interface");
|
||||
}
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
constructorToUse = AccessController.doPrivileged(
|
||||
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
|
||||
}
|
||||
else {
|
||||
constructorToUse = clazz.getDeclaredConstructor();
|
||||
}
|
||||
constructorToUse = clazz.getDeclaredConstructor();
|
||||
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
|
|
@ -107,13 +98,6 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
|||
final Constructor<?> ctor, Object... args) {
|
||||
|
||||
if (!bd.hasMethodOverrides()) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
// use own privileged to change accessibility (when security is on)
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
ReflectionUtils.makeAccessible(ctor);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
return BeanUtils.instantiateClass(ctor, args);
|
||||
}
|
||||
else {
|
||||
|
|
@ -138,15 +122,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
|
|||
@Nullable Object factoryBean, final Method factoryMethod, Object... args) {
|
||||
|
||||
try {
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
ReflectionUtils.makeAccessible(factoryMethod);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
else {
|
||||
ReflectionUtils.makeAccessible(factoryMethod);
|
||||
}
|
||||
ReflectionUtils.makeAccessible(factoryMethod);
|
||||
|
||||
Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Simple {@link SecurityContextProvider} implementation.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SimpleSecurityContextProvider implements SecurityContextProvider {
|
||||
|
||||
@Nullable
|
||||
private final AccessControlContext acc;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@code SimpleSecurityContextProvider} instance.
|
||||
* <p>The security context will be retrieved on each call from the current
|
||||
* thread.
|
||||
*/
|
||||
public SimpleSecurityContextProvider() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code SimpleSecurityContextProvider} instance.
|
||||
* <p>If the given control context is null, the security context will be
|
||||
* retrieved on each call from the current thread.
|
||||
* @param acc access control context (can be {@code null})
|
||||
* @see AccessController#getContext()
|
||||
*/
|
||||
public SimpleSecurityContextProvider(@Nullable AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AccessControlContext getAccessControlContext() {
|
||||
return (this.acc != null ? this.acc : AccessController.getContext());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,10 +20,6 @@ import java.io.Closeable;
|
|||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -41,7 +37,6 @@ import java.util.stream.Collectors;
|
|||
import java.util.stream.IntStream;
|
||||
|
||||
import javax.annotation.Priority;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -90,7 +85,6 @@ import org.springframework.core.convert.support.GenericConversionService;
|
|||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.core.testfixture.io.SerializationTestUtils;
|
||||
import org.springframework.core.testfixture.security.TestPrincipal;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
|
|
@ -2602,22 +2596,6 @@ class DefaultListableBeanFactoryTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
void initSecurityAwarePrototypeBean() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TestSecuredBean.class);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bd.setInitMethodName("init");
|
||||
lbf.registerBeanDefinition("test", bd);
|
||||
final Subject subject = new Subject();
|
||||
subject.getPrincipals().add(new TestPrincipal("user1"));
|
||||
|
||||
TestSecuredBean bean = (TestSecuredBean) Subject.doAsPrivileged(subject,
|
||||
(PrivilegedAction) () -> lbf.getBean("test"), null);
|
||||
assertThat(bean).isNotNull();
|
||||
assertThat(bean.getUserName()).isEqualTo("user1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsBeanReturnsTrueEvenForAbstractBeanDefinition() {
|
||||
lbf.registerBeanDefinition("abs", BeanDefinitionBuilder
|
||||
|
|
@ -3058,37 +3036,6 @@ class DefaultListableBeanFactoryTests {
|
|||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class TestSecuredBean {
|
||||
|
||||
private String userName;
|
||||
|
||||
void init() {
|
||||
AccessControlContext acc = AccessController.getContext();
|
||||
Subject subject = Subject.getSubject(acc);
|
||||
if (subject == null) {
|
||||
return;
|
||||
}
|
||||
setNameFromPrincipal(subject.getPrincipals());
|
||||
}
|
||||
|
||||
private void setNameFromPrincipal(Set<Principal> principals) {
|
||||
if (principals == null) {
|
||||
return;
|
||||
}
|
||||
for (Iterator<Principal> it = principals.iterator(); it.hasNext();) {
|
||||
Principal p = it.next();
|
||||
this.userName = p.getName();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return this.userName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class KnowsIfInstantiated {
|
||||
|
||||
|
|
@ -3105,7 +3052,6 @@ class DefaultListableBeanFactoryTests {
|
|||
public KnowsIfInstantiated() {
|
||||
instantiated = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,479 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.Permissions;
|
||||
import java.security.Policy;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.security.auth.AuthPermission;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.SmartFactoryBean;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.SecurityContextProvider;
|
||||
import org.springframework.beans.factory.support.security.support.ConstructorBean;
|
||||
import org.springframework.beans.factory.support.security.support.CustomCallbackBean;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.testfixture.security.TestPrincipal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Security test case. Checks whether the container uses its privileges for its
|
||||
* internal work but does not leak them when touching/calling user code.
|
||||
*
|
||||
* <p>The first half of the test case checks that permissions are downgraded when
|
||||
* calling user code while the second half that the caller code permission get
|
||||
* through and Spring doesn't override the permission stack.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CallbacksSecurityTests {
|
||||
|
||||
private DefaultListableBeanFactory beanFactory;
|
||||
private SecurityContextProvider provider;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NonPrivilegedBean {
|
||||
|
||||
private String expectedName;
|
||||
public static boolean destroyed = false;
|
||||
|
||||
public NonPrivilegedBean(String expected) {
|
||||
this.expectedName = expected;
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
checkCurrentContext();
|
||||
destroyed = true;
|
||||
}
|
||||
|
||||
public void setProperty(Object value) {
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
public Object getProperty() {
|
||||
checkCurrentContext();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setListProperty(Object value) {
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
public Object getListProperty() {
|
||||
checkCurrentContext();
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkCurrentContext() {
|
||||
assertThat(getCurrentSubjectName()).isEqualTo(expectedName);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NonPrivilegedSpringCallbacksBean implements
|
||||
InitializingBean, DisposableBean, BeanClassLoaderAware,
|
||||
BeanFactoryAware, BeanNameAware {
|
||||
|
||||
private String expectedName;
|
||||
public static boolean destroyed = false;
|
||||
|
||||
public NonPrivilegedSpringCallbacksBean(String expected) {
|
||||
this.expectedName = expected;
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
checkCurrentContext();
|
||||
destroyed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
private void checkCurrentContext() {
|
||||
assertThat(getCurrentSubjectName()).isEqualTo(expectedName);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unused", "rawtypes" })
|
||||
private static class NonPrivilegedFactoryBean implements SmartFactoryBean {
|
||||
private String expectedName;
|
||||
|
||||
public NonPrivilegedFactoryBean(String expected) {
|
||||
this.expectedName = expected;
|
||||
checkCurrentContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEagerInit() {
|
||||
checkCurrentContext();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrototype() {
|
||||
checkCurrentContext();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
checkCurrentContext();
|
||||
return new Object();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getObjectType() {
|
||||
checkCurrentContext();
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
checkCurrentContext();
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkCurrentContext() {
|
||||
assertThat(getCurrentSubjectName()).isEqualTo(expectedName);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NonPrivilegedFactory {
|
||||
|
||||
private final String expectedName;
|
||||
|
||||
public NonPrivilegedFactory(String expected) {
|
||||
this.expectedName = expected;
|
||||
assertThat(getCurrentSubjectName()).isEqualTo(expectedName);
|
||||
}
|
||||
|
||||
public static Object makeStaticInstance(String expectedName) {
|
||||
assertThat(getCurrentSubjectName()).isEqualTo(expectedName);
|
||||
return new Object();
|
||||
}
|
||||
|
||||
public Object makeInstance() {
|
||||
assertThat(getCurrentSubjectName()).isEqualTo(expectedName);
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCurrentSubjectName() {
|
||||
final AccessControlContext acc = AccessController.getContext();
|
||||
|
||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
|
||||
@Override
|
||||
public String run() {
|
||||
Subject subject = Subject.getSubject(acc);
|
||||
if (subject == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
|
||||
if (principals == null) {
|
||||
return null;
|
||||
}
|
||||
for (Principal p : principals) {
|
||||
return p.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public CallbacksSecurityTests() {
|
||||
// setup security
|
||||
if (System.getSecurityManager() == null) {
|
||||
Policy policy = Policy.getPolicy();
|
||||
URL policyURL = getClass()
|
||||
.getResource(
|
||||
"/org/springframework/beans/factory/support/security/policy.all");
|
||||
System.setProperty("java.security.policy", policyURL.toString());
|
||||
System.setProperty("policy.allowSystemProperty", "true");
|
||||
policy.refresh();
|
||||
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
|
||||
final ProtectionDomain empty = new ProtectionDomain(null,
|
||||
new Permissions());
|
||||
|
||||
provider = new SecurityContextProvider() {
|
||||
private final AccessControlContext acc = new AccessControlContext(
|
||||
new ProtectionDomain[] { empty });
|
||||
|
||||
@Override
|
||||
public AccessControlContext getAccessControlContext() {
|
||||
return acc;
|
||||
}
|
||||
};
|
||||
|
||||
DefaultResourceLoader drl = new DefaultResourceLoader();
|
||||
Resource config = drl
|
||||
.getResource("/org/springframework/beans/factory/support/security/callbacks.xml");
|
||||
beanFactory = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(config);
|
||||
beanFactory.setSecurityContextProvider(provider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecuritySanity() throws Exception {
|
||||
AccessControlContext acc = provider.getAccessControlContext();
|
||||
assertThatExceptionOfType(SecurityException.class).as(
|
||||
"Acc should not have any permissions").isThrownBy(() ->
|
||||
acc.checkPermission(new PropertyPermission("*", "read")));
|
||||
|
||||
CustomCallbackBean bean = new CustomCallbackBean();
|
||||
Method method = bean.getClass().getMethod("destroy");
|
||||
method.setAccessible(true);
|
||||
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||
method.invoke(bean);
|
||||
return null;
|
||||
}, acc));
|
||||
|
||||
Class<ConstructorBean> cl = ConstructorBean.class;
|
||||
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
|
||||
cl.newInstance(), acc));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringInitBean() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("spring-init"))
|
||||
.withCauseInstanceOf(SecurityException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomInitBean() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("custom-init"))
|
||||
.withCauseInstanceOf(SecurityException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringDestroyBean() throws Exception {
|
||||
beanFactory.getBean("spring-destroy");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(System.getProperty("security.destroy")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomDestroyBean() throws Exception {
|
||||
beanFactory.getBean("custom-destroy");
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(System.getProperty("security.destroy")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomFactoryObject() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("spring-factory"))
|
||||
.withCauseInstanceOf(SecurityException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomFactoryType() throws Exception {
|
||||
assertThat(beanFactory.getType("spring-factory")).isNull();
|
||||
assertThat(System.getProperty("factory.object.type")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomStaticFactoryMethod() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("custom-static-factory-method"))
|
||||
.satisfies(mostSpecificCauseOf(SecurityException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomInstanceFactoryMethod() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("custom-factory-method"))
|
||||
.satisfies(mostSpecificCauseOf(SecurityException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrustedFactoryMethod() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("privileged-static-factory-method"))
|
||||
.satisfies(mostSpecificCauseOf(SecurityException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("constructor"))
|
||||
.satisfies(mostSpecificCauseOf(SecurityException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContainerPrivileges() throws Exception {
|
||||
AccessControlContext acc = provider.getAccessControlContext();
|
||||
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
||||
|
||||
@Override
|
||||
public Object run() throws Exception {
|
||||
beanFactory.getBean("working-factory-method");
|
||||
beanFactory.getBean("container-execution");
|
||||
return null;
|
||||
}
|
||||
}, acc);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyInjection() throws Exception {
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() ->
|
||||
beanFactory.getBean("property-injection"))
|
||||
.withMessageContaining("security");
|
||||
beanFactory.getBean("working-property-injection");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitSecurityAwarePrototypeBean() {
|
||||
final DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
|
||||
BeanDefinitionBuilder bdb = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(NonPrivilegedBean.class).setScope(
|
||||
BeanDefinition.SCOPE_PROTOTYPE)
|
||||
.setInitMethodName("init").setDestroyMethodName("destroy")
|
||||
.addConstructorArgValue("user1");
|
||||
lbf.registerBeanDefinition("test", bdb.getBeanDefinition());
|
||||
final Subject subject = new Subject();
|
||||
subject.getPrincipals().add(new TestPrincipal("user1"));
|
||||
|
||||
NonPrivilegedBean bean = Subject.doAsPrivileged(
|
||||
subject, new PrivilegedAction<NonPrivilegedBean>() {
|
||||
@Override
|
||||
public NonPrivilegedBean run() {
|
||||
return lbf.getBean("test", NonPrivilegedBean.class);
|
||||
}
|
||||
}, null);
|
||||
assertThat(bean).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrustedExecution() throws Exception {
|
||||
beanFactory.setSecurityContextProvider(null);
|
||||
|
||||
Permissions perms = new Permissions();
|
||||
perms.add(new AuthPermission("getSubject"));
|
||||
ProtectionDomain pd = new ProtectionDomain(null, perms);
|
||||
|
||||
new AccessControlContext(new ProtectionDomain[] { pd });
|
||||
|
||||
final Subject subject = new Subject();
|
||||
subject.getPrincipals().add(new TestPrincipal("user1"));
|
||||
|
||||
// request the beans from non-privileged code
|
||||
Subject.doAsPrivileged(subject, new PrivilegedAction<Object>() {
|
||||
|
||||
@Override
|
||||
public Object run() {
|
||||
// sanity check
|
||||
assertThat(getCurrentSubjectName()).isEqualTo("user1");
|
||||
assertThat(NonPrivilegedBean.destroyed).isEqualTo(false);
|
||||
|
||||
beanFactory.getBean("trusted-spring-callbacks");
|
||||
beanFactory.getBean("trusted-custom-init-destroy");
|
||||
// the factory is a prototype - ask for multiple instances
|
||||
beanFactory.getBean("trusted-spring-factory");
|
||||
beanFactory.getBean("trusted-spring-factory");
|
||||
beanFactory.getBean("trusted-spring-factory");
|
||||
|
||||
beanFactory.getBean("trusted-factory-bean");
|
||||
beanFactory.getBean("trusted-static-factory-method");
|
||||
beanFactory.getBean("trusted-factory-method");
|
||||
beanFactory.getBean("trusted-property-injection");
|
||||
beanFactory.getBean("trusted-working-property-injection");
|
||||
|
||||
beanFactory.destroySingletons();
|
||||
assertThat(NonPrivilegedBean.destroyed).isEqualTo(true);
|
||||
return null;
|
||||
}
|
||||
}, provider.getAccessControlContext());
|
||||
}
|
||||
|
||||
private <E extends NestedRuntimeException> Consumer<E> mostSpecificCauseOf(Class<? extends Throwable> type) {
|
||||
return ex -> assertThat(ex.getMostSpecificCause()).isInstanceOf(type);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class ConstructorBean {
|
||||
|
||||
public ConstructorBean() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public ConstructorBean(Object obj) {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomCallbackBean {
|
||||
|
||||
public void init() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomFactoryBean implements FactoryBean<Properties> {
|
||||
|
||||
@Override
|
||||
public Properties getObject() throws Exception {
|
||||
return System.getProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Properties> getObjectType() {
|
||||
System.setProperty("factory.object.type", "true");
|
||||
return Properties.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DestroyBean implements DisposableBean {
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class FactoryBean {
|
||||
|
||||
public static Object makeStaticInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
|
||||
protected static Object protectedStaticInstance() {
|
||||
return "protectedStaticInstance";
|
||||
}
|
||||
|
||||
public Object makeInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class InitBean implements InitializingBean {
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
System.getProperties();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class PropertyBean {
|
||||
|
||||
public void setSecurityProperty(Object property) {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void setProperty(Object property) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -502,7 +502,7 @@ class CustomEditorTests {
|
|||
CharBean cb = new CharBean();
|
||||
BeanWrapper bw = new BeanWrapperImpl(cb);
|
||||
|
||||
bw.setPropertyValue("myChar", new Character('c'));
|
||||
bw.setPropertyValue("myChar", Character.valueOf('c'));
|
||||
assertThat(cb.getMyChar()).isEqualTo('c');
|
||||
|
||||
bw.setPropertyValue("myChar", "c");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
package org.springframework.context.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.EmbeddedValueResolver;
|
||||
|
|
@ -86,22 +82,7 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
|
|||
return bean;
|
||||
}
|
||||
|
||||
AccessControlContext acc = null;
|
||||
|
||||
if (System.getSecurityManager() != null) {
|
||||
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
|
||||
}
|
||||
|
||||
if (acc != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
invokeAwareInterfaces(bean);
|
||||
return null;
|
||||
}, acc);
|
||||
}
|
||||
else {
|
||||
invokeAwareInterfaces(bean);
|
||||
}
|
||||
|
||||
invokeAwareInterfaces(bean);
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -22,9 +22,6 @@ import java.io.InputStreamReader;
|
|||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
|
@ -400,28 +397,19 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou
|
|||
final String resourceName = toResourceName(bundleName, "properties");
|
||||
final ClassLoader classLoader = loader;
|
||||
final boolean reloadFlag = reload;
|
||||
InputStream inputStream;
|
||||
try {
|
||||
inputStream = AccessController.doPrivileged((PrivilegedExceptionAction<InputStream>) () -> {
|
||||
InputStream is = null;
|
||||
if (reloadFlag) {
|
||||
URL url = classLoader.getResource(resourceName);
|
||||
if (url != null) {
|
||||
URLConnection connection = url.openConnection();
|
||||
if (connection != null) {
|
||||
connection.setUseCaches(false);
|
||||
is = connection.getInputStream();
|
||||
}
|
||||
}
|
||||
InputStream inputStream = null;
|
||||
if (reloadFlag) {
|
||||
URL url = classLoader.getResource(resourceName);
|
||||
if (url != null) {
|
||||
URLConnection connection = url.openConnection();
|
||||
if (connection != null) {
|
||||
connection.setUseCaches(false);
|
||||
inputStream = connection.getInputStream();
|
||||
}
|
||||
else {
|
||||
is = classLoader.getResourceAsStream(resourceName);
|
||||
}
|
||||
return is;
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (PrivilegedActionException ex) {
|
||||
throw (IOException) ex.getException();
|
||||
else {
|
||||
inputStream = classLoader.getResourceAsStream(resourceName);
|
||||
}
|
||||
if (inputStream != null) {
|
||||
String encoding = getDefaultEncoding();
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ import java.io.Reader;
|
|||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.Permission;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
|
||||
|
|
@ -237,43 +235,6 @@ class ApplicationContextExpressionTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void systemPropertiesSecurityManager() {
|
||||
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
|
||||
|
||||
GenericBeanDefinition bd = new GenericBeanDefinition();
|
||||
bd.setBeanClass(TestBean.class);
|
||||
bd.getPropertyValues().add("country", "#{systemProperties.country}");
|
||||
ac.registerBeanDefinition("tb", bd);
|
||||
|
||||
SecurityManager oldSecurityManager = System.getSecurityManager();
|
||||
try {
|
||||
System.setProperty("country", "NL");
|
||||
|
||||
SecurityManager securityManager = new SecurityManager() {
|
||||
@Override
|
||||
public void checkPropertiesAccess() {
|
||||
throw new AccessControlException("Not Allowed");
|
||||
}
|
||||
@Override
|
||||
public void checkPermission(Permission perm) {
|
||||
// allow everything else
|
||||
}
|
||||
};
|
||||
System.setSecurityManager(securityManager);
|
||||
ac.refresh();
|
||||
|
||||
TestBean tb = ac.getBean("tb", TestBean.class);
|
||||
assertThat(tb.getCountry()).isEqualTo("NL");
|
||||
|
||||
}
|
||||
finally {
|
||||
System.setSecurityManager(oldSecurityManager);
|
||||
System.getProperties().remove("country");
|
||||
}
|
||||
ac.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void stringConcatenationWithDebugLogging() {
|
||||
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
|
||||
|
|
|
|||
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.support;
|
||||
|
||||
import java.security.AccessControlException;
|
||||
import java.security.Permission;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.testfixture.env.EnvironmentTestUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests integration between Environment and SecurityManagers. See SPR-9970.
|
||||
*
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class EnvironmentSecurityManagerIntegrationTests {
|
||||
|
||||
private SecurityManager originalSecurityManager;
|
||||
|
||||
private Map<String, String> env;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
originalSecurityManager = System.getSecurityManager();
|
||||
env = EnvironmentTestUtils.getModifiableSystemEnvironment();
|
||||
env.put(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "p1");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
env.remove(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME);
|
||||
System.setSecurityManager(originalSecurityManager);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void securityManagerDisallowsAccessToSystemEnvironmentButAllowsAccessToIndividualKeys() {
|
||||
SecurityManager securityManager = new SecurityManager() {
|
||||
@Override
|
||||
public void checkPermission(Permission perm) {
|
||||
// Disallowing access to System#getenv means that our
|
||||
// ReadOnlySystemAttributesMap will come into play.
|
||||
if ("getenv.*".equals(perm.getName())) {
|
||||
throw new AccessControlException("Accessing the system environment is disallowed");
|
||||
}
|
||||
}
|
||||
};
|
||||
System.setSecurityManager(securityManager);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(bf);
|
||||
reader.register(C1.class);
|
||||
assertThat(bf.containsBean("c1")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void securityManagerDisallowsAccessToSystemEnvironmentAndDisallowsAccessToIndividualKey() {
|
||||
SecurityManager securityManager = new SecurityManager() {
|
||||
@Override
|
||||
public void checkPermission(Permission perm) {
|
||||
// Disallowing access to System#getenv means that our
|
||||
// ReadOnlySystemAttributesMap will come into play.
|
||||
if ("getenv.*".equals(perm.getName())) {
|
||||
throw new AccessControlException("Accessing the system environment is disallowed");
|
||||
}
|
||||
// Disallowing access to the spring.profiles.active property means that
|
||||
// the BeanDefinitionReader won't be able to determine which profiles are
|
||||
// active. We should see an INFO-level message in the console about this
|
||||
// and as a result, any components marked with a non-default profile will
|
||||
// be ignored.
|
||||
if (("getenv." + AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME).equals(perm.getName())) {
|
||||
throw new AccessControlException(
|
||||
format("Accessing system environment variable [%s] is disallowed",
|
||||
AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME));
|
||||
}
|
||||
}
|
||||
};
|
||||
System.setSecurityManager(securityManager);
|
||||
|
||||
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
|
||||
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(bf);
|
||||
reader.register(C1.class);
|
||||
assertThat(bf.containsBean("c1")).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@Component("c1")
|
||||
@Profile("p1")
|
||||
static class C1 {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -19,8 +19,6 @@ package org.springframework.jmx.support;
|
|||
import java.beans.PropertyDescriptor;
|
||||
|
||||
import javax.management.DynamicMBean;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerFactory;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.ObjectName;
|
||||
|
|
@ -57,42 +55,42 @@ class JmxUtilsTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void isMBeanWithDynamicMBean() throws Exception {
|
||||
void isMBeanWithDynamicMBean() {
|
||||
DynamicMBean mbean = new TestDynamicMBean();
|
||||
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Dynamic MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isMBeanWithStandardMBeanWrapper() throws Exception {
|
||||
void isMBeanWithStandardMBeanWrapper() throws NotCompliantMBeanException {
|
||||
StandardMBean mbean = new StandardMBean(new JmxTestBean(), IJmxTestBean.class);
|
||||
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isMBeanWithStandardMBeanInherited() throws Exception {
|
||||
void isMBeanWithStandardMBeanInherited() throws NotCompliantMBeanException {
|
||||
StandardMBean mbean = new StandardMBeanImpl();
|
||||
assertThat(JmxUtils.isMBean(mbean.getClass())).as("Standard MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void notAnMBean() throws Exception {
|
||||
void notAnMBean() {
|
||||
assertThat(JmxUtils.isMBean(Object.class)).as("Object incorrectly identified as an MBean").isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleMBean() throws Exception {
|
||||
void simpleMBean() {
|
||||
Foo foo = new Foo();
|
||||
assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleMXBean() throws Exception {
|
||||
void simpleMXBean() {
|
||||
FooX foo = new FooX();
|
||||
assertThat(JmxUtils.isMBean(foo.getClass())).as("Simple MXBean not detected correctly").isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleMBeanThroughInheritance() throws Exception {
|
||||
void simpleMBeanThroughInheritance() {
|
||||
Bar bar = new Bar();
|
||||
Abc abc = new Abc();
|
||||
assertThat(JmxUtils.isMBean(bar.getClass())).as("Simple MBean (through inheritance) not detected correctly").isTrue();
|
||||
|
|
@ -126,19 +124,6 @@ class JmxUtilsTests {
|
|||
assertThat(uniqueName.getKeyProperty(JmxUtils.IDENTITY_OBJECT_NAME_KEY)).as("Identity key is incorrect").isEqualTo(ObjectUtils.getIdentityHexString(managedResource));
|
||||
}
|
||||
|
||||
@Test
|
||||
void locatePlatformMBeanServer() {
|
||||
MBeanServer server = null;
|
||||
try {
|
||||
server = JmxUtils.locateMBeanServer();
|
||||
}
|
||||
finally {
|
||||
if (server != null) {
|
||||
MBeanServerFactory.releaseMBeanServer(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class AttributeTestBean {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -47,7 +47,7 @@ class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void defaultValues() throws Exception {
|
||||
void defaultValues() {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.afterPropertiesSet();
|
||||
try {
|
||||
|
|
@ -60,7 +60,7 @@ class MBeanServerFactoryBeanTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void defaultDomain() throws Exception {
|
||||
void defaultDomain() {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.setDefaultDomain("foo");
|
||||
bean.afterPropertiesSet();
|
||||
|
|
@ -129,7 +129,8 @@ class MBeanServerFactoryBeanTests {
|
|||
assertCreation(false, "The server should not be available in the list");
|
||||
}
|
||||
|
||||
private void assertCreation(boolean referenceShouldExist, String failMsg) throws Exception {
|
||||
|
||||
private void assertCreation(boolean referenceShouldExist, String failMsg) {
|
||||
MBeanServerFactoryBean bean = new MBeanServerFactoryBean();
|
||||
bean.setRegisterWithFactory(referenceShouldExist);
|
||||
bean.afterPropertiesSet();
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jndi;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.naming.spi.NamingManager;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tests for {@link JndiLocatorDelegate}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class JndiLocatorDelegateTests {
|
||||
|
||||
@Test
|
||||
public void isDefaultJndiEnvironmentAvailableFalse() throws Exception {
|
||||
Field builderField = NamingManager.class.getDeclaredField("initctx_factory_builder");
|
||||
builderField.setAccessible(true);
|
||||
Object oldBuilder = builderField.get(null);
|
||||
builderField.set(null, null);
|
||||
|
||||
try {
|
||||
assertThat(JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()).isEqualTo(false);
|
||||
}
|
||||
finally {
|
||||
builderField.set(null, oldBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -16,9 +16,6 @@
|
|||
|
||||
package org.springframework.util;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerFactory;
|
||||
|
||||
|
|
@ -45,10 +42,6 @@ public class MBeanTestUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer");
|
||||
field.setAccessible(true);
|
||||
field.set(null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -56,11 +53,6 @@ public class ReflectUtils {
|
|||
|
||||
private static final ClassLoader defaultLoader = ReflectUtils.class.getClassLoader();
|
||||
|
||||
// SPRING PATCH BEGIN
|
||||
private static final Method privateLookupInMethod;
|
||||
|
||||
private static final Method lookupDefineClassMethod;
|
||||
|
||||
private static final Method classLoaderDefineClassMethod;
|
||||
|
||||
private static final ProtectionDomain PROTECTION_DOMAIN;
|
||||
|
|
@ -69,63 +61,28 @@ public class ReflectUtils {
|
|||
|
||||
private static final List<Method> OBJECT_METHODS = new ArrayList<Method>();
|
||||
|
||||
// SPRING PATCH BEGIN
|
||||
static {
|
||||
Method privateLookupIn;
|
||||
Method lookupDefineClass;
|
||||
Method classLoaderDefineClass;
|
||||
ProtectionDomain protectionDomain;
|
||||
Throwable throwable = null;
|
||||
try {
|
||||
privateLookupIn = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
try {
|
||||
return MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
lookupDefineClass = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
try {
|
||||
return MethodHandles.Lookup.class.getMethod("defineClass", byte[].class);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
classLoaderDefineClass = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
return ClassLoader.class.getDeclaredMethod("defineClass",
|
||||
classLoaderDefineClass = ClassLoader.class.getDeclaredMethod("defineClass",
|
||||
String.class, byte[].class, Integer.TYPE, Integer.TYPE, ProtectionDomain.class);
|
||||
}
|
||||
});
|
||||
protectionDomain = getProtectionDomain(ReflectUtils.class);
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() throws Exception {
|
||||
Method[] methods = Object.class.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
if ("finalize".equals(method.getName())
|
||||
|| (method.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) > 0) {
|
||||
continue;
|
||||
}
|
||||
OBJECT_METHODS.add(method);
|
||||
}
|
||||
return null;
|
||||
for (Method method : Object.class.getDeclaredMethods()) {
|
||||
if ("finalize".equals(method.getName())
|
||||
|| (method.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) > 0) {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
OBJECT_METHODS.add(method);
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
privateLookupIn = null;
|
||||
lookupDefineClass = null;
|
||||
classLoaderDefineClass = null;
|
||||
protectionDomain = null;
|
||||
throwable = t;
|
||||
}
|
||||
privateLookupInMethod = privateLookupIn;
|
||||
lookupDefineClassMethod = lookupDefineClass;
|
||||
classLoaderDefineClassMethod = classLoaderDefineClass;
|
||||
PROTECTION_DOMAIN = protectionDomain;
|
||||
THROWABLE = throwable;
|
||||
|
|
@ -160,11 +117,7 @@ public class ReflectUtils {
|
|||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return (ProtectionDomain) AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
return source.getProtectionDomain();
|
||||
}
|
||||
});
|
||||
return source.getProtectionDomain();
|
||||
}
|
||||
|
||||
public static Type[] getExceptionTypes(Member member) {
|
||||
|
|
@ -336,15 +289,7 @@ public class ReflectUtils {
|
|||
public static Constructor getConstructor(Class type, Class[] parameterTypes) {
|
||||
try {
|
||||
Constructor constructor = type.getDeclaredConstructor(parameterTypes);
|
||||
if (System.getSecurityManager() != null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
constructor.setAccessible(true);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
else {
|
||||
constructor.setAccessible(true);
|
||||
}
|
||||
constructor.setAccessible(true);
|
||||
return constructor;
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
|
|
@ -501,18 +446,12 @@ public class ReflectUtils {
|
|||
Class c = null;
|
||||
|
||||
// Preferred option: JDK 9+ Lookup.defineClass API if ClassLoader matches
|
||||
if (contextClass != null && contextClass.getClassLoader() == loader &&
|
||||
privateLookupInMethod != null && lookupDefineClassMethod != null) {
|
||||
if (contextClass != null && contextClass.getClassLoader() == loader) {
|
||||
try {
|
||||
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
|
||||
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
|
||||
c = (Class) lookupDefineClassMethod.invoke(lookup, b);
|
||||
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(contextClass, MethodHandles.lookup());
|
||||
c = lookup.defineClass(b);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
Throwable target = ex.getTargetException();
|
||||
if (target.getClass() != LinkageError.class && target.getClass() != IllegalArgumentException.class) {
|
||||
throw new CodeGenerationException(target);
|
||||
}
|
||||
catch (LinkageError | IllegalArgumentException ex) {
|
||||
// in case of plain LinkageError (class already defined)
|
||||
// or IllegalArgumentException (class in different package):
|
||||
// fall through to traditional ClassLoader.defineClass below
|
||||
|
|
@ -567,15 +506,10 @@ public class ReflectUtils {
|
|||
}
|
||||
|
||||
// Fallback option: JDK 9+ Lookup.defineClass API even if ClassLoader does not match
|
||||
if (c == null && contextClass != null && contextClass.getClassLoader() != loader &&
|
||||
privateLookupInMethod != null && lookupDefineClassMethod != null) {
|
||||
if (c == null && contextClass != null && contextClass.getClassLoader() != loader) {
|
||||
try {
|
||||
MethodHandles.Lookup lookup = (MethodHandles.Lookup)
|
||||
privateLookupInMethod.invoke(null, contextClass, MethodHandles.lookup());
|
||||
c = (Class) lookupDefineClassMethod.invoke(lookup, b);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new CodeGenerationException(ex.getTargetException());
|
||||
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(contextClass, MethodHandles.lookup());
|
||||
c = lookup.defineClass(b);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new CodeGenerationException(ex);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.springframework.core.env;
|
||||
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
|
|
@ -60,8 +59,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
* <p>The default is "false", falling back to system environment variable checks if a
|
||||
* Spring environment property (e.g. a placeholder in a configuration String) isn't
|
||||
* resolvable otherwise. Consider switching this flag to "true" if you experience
|
||||
* log warnings from {@code getenv} calls coming from Spring, e.g. on WebSphere
|
||||
* with strict SecurityManager settings and AccessControlExceptions warnings.
|
||||
* log warnings from {@code getenv} calls coming from Spring.
|
||||
* @see #suppressGetenvAccess()
|
||||
*/
|
||||
public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";
|
||||
|
|
@ -438,27 +436,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public Map<String, Object> getSystemProperties() {
|
||||
try {
|
||||
return (Map) System.getProperties();
|
||||
}
|
||||
catch (AccessControlException ex) {
|
||||
return (Map) new ReadOnlySystemAttributesMap() {
|
||||
@Override
|
||||
@Nullable
|
||||
protected String getSystemAttribute(String attributeName) {
|
||||
try {
|
||||
return System.getProperty(attributeName);
|
||||
}
|
||||
catch (AccessControlException ex) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Caught AccessControlException when accessing system property '" +
|
||||
attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return (Map) System.getProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -467,27 +445,7 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
|
|||
if (suppressGetenvAccess()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
try {
|
||||
return (Map) System.getenv();
|
||||
}
|
||||
catch (AccessControlException ex) {
|
||||
return (Map) new ReadOnlySystemAttributesMap() {
|
||||
@Override
|
||||
@Nullable
|
||||
protected String getSystemAttribute(String attributeName) {
|
||||
try {
|
||||
return System.getenv(attributeName);
|
||||
}
|
||||
catch (AccessControlException ex) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Caught AccessControlException when accessing system environment variable '" +
|
||||
attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return (Map) System.getenv();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -119,32 +119,20 @@ public interface ConfigurableEnvironment extends Environment, ConfigurableProper
|
|||
MutablePropertySources getPropertySources();
|
||||
|
||||
/**
|
||||
* Return the value of {@link System#getProperties()} if allowed by the current
|
||||
* {@link SecurityManager}, otherwise return a map implementation that will attempt
|
||||
* to access individual keys using calls to {@link System#getProperty(String)}.
|
||||
* Return the value of {@link System#getProperties()}.
|
||||
* <p>Note that most {@code Environment} implementations will include this system
|
||||
* properties map as a default {@link PropertySource} to be searched. Therefore, it is
|
||||
* recommended that this method not be used directly unless bypassing other property
|
||||
* sources is expressly intended.
|
||||
* <p>Calls to {@link Map#get(Object)} on the Map returned will never throw
|
||||
* {@link IllegalAccessException}; in cases where the SecurityManager forbids access
|
||||
* to a property, {@code null} will be returned and an INFO-level log message will be
|
||||
* issued noting the exception.
|
||||
*/
|
||||
Map<String, Object> getSystemProperties();
|
||||
|
||||
/**
|
||||
* Return the value of {@link System#getenv()} if allowed by the current
|
||||
* {@link SecurityManager}, otherwise return a map implementation that will attempt
|
||||
* to access individual keys using calls to {@link System#getenv(String)}.
|
||||
* Return the value of {@link System#getenv()}.
|
||||
* <p>Note that most {@link Environment} implementations will include this system
|
||||
* environment map as a default {@link PropertySource} to be searched. Therefore, it
|
||||
* is recommended that this method not be used directly unless bypassing other
|
||||
* property sources is expressly intended.
|
||||
* <p>Calls to {@link Map#get(Object)} on the Map returned will never throw
|
||||
* {@link IllegalAccessException}; in cases where the SecurityManager forbids access
|
||||
* to a property, {@code null} will be returned and an INFO-level log message will be
|
||||
* issued noting the exception.
|
||||
*/
|
||||
Map<String, Object> getSystemEnvironment();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.core.env;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Read-only {@code Map<String, String>} implementation that is backed by system
|
||||
* properties or environment variables.
|
||||
*
|
||||
* <p>Used by {@link AbstractEnvironment} when a {@link SecurityManager} prohibits
|
||||
* access to {@link System#getProperties()} or {@link System#getenv()}. It is for this
|
||||
* reason that the implementations of {@link #keySet()}, {@link #entrySet()}, and
|
||||
* {@link #values()} always return empty even though {@link #get(Object)} may in fact
|
||||
* return non-null if the current security manager allows access to individual keys.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
*/
|
||||
abstract class ReadOnlySystemAttributesMap implements Map<String, String> {
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return (get(key) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value to which the specified key is mapped, or {@code null} if this map
|
||||
* contains no mapping for the key.
|
||||
* @param key the name of the system attribute to retrieve
|
||||
* @throws IllegalArgumentException if given key is non-String
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public String get(Object key) {
|
||||
if (!(key instanceof String)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Type of key [" + key.getClass().getName() + "] must be java.lang.String");
|
||||
}
|
||||
return getSystemAttribute((String) key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method that returns the underlying system attribute.
|
||||
* <p>Implementations typically call {@link System#getProperty(String)} or {@link System#getenv(String)} here.
|
||||
*/
|
||||
@Nullable
|
||||
protected abstract String getSystemAttribute(String attributeName);
|
||||
|
||||
|
||||
// Unsupported
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String put(String key, String value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String remove(Object key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends String, ? extends String> map) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> values() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, String>> entrySet() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -122,34 +122,26 @@ public class SystemEnvironmentPropertySource extends MapPropertySource {
|
|||
@Nullable
|
||||
private String checkPropertyName(String name) {
|
||||
// Check name as-is
|
||||
if (containsKey(name)) {
|
||||
if (this.source.containsKey(name)) {
|
||||
return name;
|
||||
}
|
||||
// Check name with just dots replaced
|
||||
String noDotName = name.replace('.', '_');
|
||||
if (!name.equals(noDotName) && containsKey(noDotName)) {
|
||||
if (!name.equals(noDotName) && this.source.containsKey(noDotName)) {
|
||||
return noDotName;
|
||||
}
|
||||
// Check name with just hyphens replaced
|
||||
String noHyphenName = name.replace('-', '_');
|
||||
if (!name.equals(noHyphenName) && containsKey(noHyphenName)) {
|
||||
if (!name.equals(noHyphenName) && this.source.containsKey(noHyphenName)) {
|
||||
return noHyphenName;
|
||||
}
|
||||
// Check name with dots and hyphens replaced
|
||||
String noDotNoHyphenName = noDotName.replace('-', '_');
|
||||
if (!noDotName.equals(noDotNoHyphenName) && containsKey(noDotNoHyphenName)) {
|
||||
if (!noDotName.equals(noDotNoHyphenName) && this.source.containsKey(noDotNoHyphenName)) {
|
||||
return noDotNoHyphenName;
|
||||
}
|
||||
// Give up
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean containsKey(String name) {
|
||||
return (isSecurityManagerPresent() ? this.source.keySet().contains(name) : this.source.containsKey(name));
|
||||
}
|
||||
|
||||
protected boolean isSecurityManagerPresent() {
|
||||
return (System.getSecurityManager() != null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.core.type.classreading;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.AccessControlException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
|
@ -97,7 +96,7 @@ abstract class AbstractRecursiveAnnotationVisitor extends AnnotationVisitor {
|
|||
catch (ClassNotFoundException | NoClassDefFoundError ex) {
|
||||
logger.debug("Failed to classload enum type while reading annotation metadata", ex);
|
||||
}
|
||||
catch (IllegalAccessException | AccessControlException ex) {
|
||||
catch (IllegalAccessException ex) {
|
||||
logger.debug("Could not access enum value while reading annotation metadata", ex);
|
||||
}
|
||||
return valueToUse;
|
||||
|
|
|
|||
|
|
@ -107,9 +107,7 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib
|
|||
String annotationName = annotationType.getName();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && visited.add(annotation)) {
|
||||
try {
|
||||
// Only do attribute scanning for public annotations; we'd run into
|
||||
// IllegalAccessExceptions otherwise, and we don't want to mess with
|
||||
// accessibility in a SecurityManager environment.
|
||||
// Only do attribute scanning for public annotations.
|
||||
if (Modifier.isPublic(annotationType.getModifiers())) {
|
||||
this.attributesMap.add(annotationName,
|
||||
AnnotationUtils.getAnnotationAttributes(annotation, false, true));
|
||||
|
|
|
|||
|
|
@ -190,8 +190,7 @@ public abstract class ReflectionUtils {
|
|||
/**
|
||||
* Make the given constructor accessible, explicitly setting it accessible
|
||||
* if necessary. The {@code setAccessible(true)} method is only called
|
||||
* when actually necessary, to avoid unnecessary conflicts with a JVM
|
||||
* SecurityManager (if active).
|
||||
* when actually necessary, to avoid unnecessary conflicts.
|
||||
* @param ctor the constructor to make accessible
|
||||
* @see java.lang.reflect.Constructor#setAccessible
|
||||
*/
|
||||
|
|
@ -441,10 +440,9 @@ public abstract class ReflectionUtils {
|
|||
|
||||
/**
|
||||
* Variant of {@link Class#getDeclaredMethods()} that uses a local cache in
|
||||
* order to avoid the JVM's SecurityManager check and new Method instances.
|
||||
* In addition, it also includes Java 8 default methods from locally
|
||||
* implemented interfaces, since those are effectively to be treated just
|
||||
* like declared methods.
|
||||
* order to avoid new Method instances. In addition, it also includes Java 8
|
||||
* default methods from locally implemented interfaces, since those are
|
||||
* effectively to be treated just like declared methods.
|
||||
* @param clazz the class to introspect
|
||||
* @return the cached array of methods
|
||||
* @throws IllegalStateException if introspection fails
|
||||
|
|
@ -561,8 +559,7 @@ public abstract class ReflectionUtils {
|
|||
/**
|
||||
* Make the given method accessible, explicitly setting it accessible if
|
||||
* necessary. The {@code setAccessible(true)} method is only called
|
||||
* when actually necessary, to avoid unnecessary conflicts with a JVM
|
||||
* SecurityManager (if active).
|
||||
* when actually necessary, to avoid unnecessary conflicts.
|
||||
* @param method the method to make accessible
|
||||
* @see java.lang.reflect.Method#setAccessible
|
||||
*/
|
||||
|
|
@ -720,7 +717,7 @@ public abstract class ReflectionUtils {
|
|||
|
||||
/**
|
||||
* This variant retrieves {@link Class#getDeclaredFields()} from a local cache
|
||||
* in order to avoid the JVM's SecurityManager check and defensive array copying.
|
||||
* in order to avoid defensive array copying.
|
||||
* @param clazz the class to introspect
|
||||
* @return the cached array of fields
|
||||
* @throws IllegalStateException if introspection fails
|
||||
|
|
@ -774,8 +771,7 @@ public abstract class ReflectionUtils {
|
|||
/**
|
||||
* Make the given field accessible, explicitly setting it accessible if
|
||||
* necessary. The {@code setAccessible(true)} method is only called
|
||||
* when actually necessary, to avoid unnecessary conflicts with a JVM
|
||||
* SecurityManager (if active).
|
||||
* when actually necessary, to avoid unnecessary conflicts.
|
||||
* @param field the field to make accessible
|
||||
* @see java.lang.reflect.Field#setAccessible
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -16,15 +16,12 @@
|
|||
|
||||
package org.springframework.core.env;
|
||||
|
||||
import java.security.AccessControlException;
|
||||
import java.security.Permission;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.SpringProperties;
|
||||
import org.springframework.core.testfixture.env.EnvironmentTestUtils;
|
||||
import org.springframework.core.testfixture.env.MockPropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
|
@ -381,72 +378,22 @@ public class StandardEnvironmentTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void getSystemProperties_withAndWithoutSecurityManager() {
|
||||
void getSystemProperties() {
|
||||
System.setProperty(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE);
|
||||
System.setProperty(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE);
|
||||
System.getProperties().put(STRING_PROPERTY_NAME, NON_STRING_PROPERTY_VALUE);
|
||||
System.getProperties().put(NON_STRING_PROPERTY_NAME, STRING_PROPERTY_VALUE);
|
||||
|
||||
{
|
||||
try {
|
||||
Map<?, ?> systemProperties = environment.getSystemProperties();
|
||||
assertThat(systemProperties).isNotNull();
|
||||
assertThat(System.getProperties()).isSameAs(systemProperties);
|
||||
assertThat(systemProperties.get(ALLOWED_PROPERTY_NAME)).isEqualTo(ALLOWED_PROPERTY_VALUE);
|
||||
assertThat(systemProperties.get(DISALLOWED_PROPERTY_NAME)).isEqualTo(DISALLOWED_PROPERTY_VALUE);
|
||||
|
||||
// non-string keys and values work fine... until the security manager is introduced below
|
||||
assertThat(systemProperties.get(STRING_PROPERTY_NAME)).isEqualTo(NON_STRING_PROPERTY_VALUE);
|
||||
assertThat(systemProperties.get(NON_STRING_PROPERTY_NAME)).isEqualTo(STRING_PROPERTY_VALUE);
|
||||
}
|
||||
|
||||
SecurityManager oldSecurityManager = System.getSecurityManager();
|
||||
SecurityManager securityManager = new SecurityManager() {
|
||||
@Override
|
||||
public void checkPropertiesAccess() {
|
||||
// see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getProperties()
|
||||
throw new AccessControlException("Accessing the system properties is disallowed");
|
||||
}
|
||||
@Override
|
||||
public void checkPropertyAccess(String key) {
|
||||
// see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getProperty(java.lang.String)
|
||||
if (DISALLOWED_PROPERTY_NAME.equals(key)) {
|
||||
throw new AccessControlException(
|
||||
String.format("Accessing the system property [%s] is disallowed", DISALLOWED_PROPERTY_NAME));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void checkPermission(Permission perm) {
|
||||
// allow everything else
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
System.setSecurityManager(securityManager);
|
||||
|
||||
{
|
||||
Map<?, ?> systemProperties = environment.getSystemProperties();
|
||||
assertThat(systemProperties).isNotNull();
|
||||
assertThat(systemProperties).isInstanceOf(ReadOnlySystemAttributesMap.class);
|
||||
assertThat((String)systemProperties.get(ALLOWED_PROPERTY_NAME)).isEqualTo(ALLOWED_PROPERTY_VALUE);
|
||||
assertThat(systemProperties.get(DISALLOWED_PROPERTY_NAME)).isNull();
|
||||
|
||||
// nothing we can do here in terms of warning the user that there was
|
||||
// actually a (non-string) value available. By this point, we only
|
||||
// have access to calling System.getProperty(), which itself returns null
|
||||
// if the value is non-string. So we're stuck with returning a potentially
|
||||
// misleading null.
|
||||
assertThat(systemProperties.get(STRING_PROPERTY_NAME)).isNull();
|
||||
|
||||
// in the case of a non-string *key*, however, we can do better. Alert
|
||||
// the user that under these very special conditions (non-object key +
|
||||
// SecurityManager that disallows access to system properties), they
|
||||
// cannot do what they're attempting.
|
||||
assertThatIllegalArgumentException().as("searching with non-string key against ReadOnlySystemAttributesMap").isThrownBy(() ->
|
||||
systemProperties.get(NON_STRING_PROPERTY_NAME));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
System.setSecurityManager(oldSecurityManager);
|
||||
System.clearProperty(ALLOWED_PROPERTY_NAME);
|
||||
System.clearProperty(DISALLOWED_PROPERTY_NAME);
|
||||
System.getProperties().remove(STRING_PROPERTY_NAME);
|
||||
|
|
@ -455,48 +402,10 @@ public class StandardEnvironmentTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void getSystemEnvironment_withAndWithoutSecurityManager() {
|
||||
EnvironmentTestUtils.getModifiableSystemEnvironment().put(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE);
|
||||
EnvironmentTestUtils.getModifiableSystemEnvironment().put(DISALLOWED_PROPERTY_NAME, DISALLOWED_PROPERTY_VALUE);
|
||||
|
||||
{
|
||||
Map<String, Object> systemEnvironment = environment.getSystemEnvironment();
|
||||
assertThat(systemEnvironment).isNotNull();
|
||||
assertThat(System.getenv()).isSameAs(systemEnvironment);
|
||||
}
|
||||
|
||||
SecurityManager oldSecurityManager = System.getSecurityManager();
|
||||
SecurityManager securityManager = new SecurityManager() {
|
||||
@Override
|
||||
public void checkPermission(Permission perm) {
|
||||
//see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getenv()
|
||||
if ("getenv.*".equals(perm.getName())) {
|
||||
throw new AccessControlException("Accessing the system environment is disallowed");
|
||||
}
|
||||
//see https://download.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#getenv(java.lang.String)
|
||||
if (("getenv."+DISALLOWED_PROPERTY_NAME).equals(perm.getName())) {
|
||||
throw new AccessControlException(
|
||||
String.format("Accessing the system environment variable [%s] is disallowed", DISALLOWED_PROPERTY_NAME));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
System.setSecurityManager(securityManager);
|
||||
{
|
||||
Map<String, Object> systemEnvironment = environment.getSystemEnvironment();
|
||||
assertThat(systemEnvironment).isNotNull();
|
||||
assertThat(systemEnvironment).isInstanceOf(ReadOnlySystemAttributesMap.class);
|
||||
assertThat(systemEnvironment.get(ALLOWED_PROPERTY_NAME)).isEqualTo(ALLOWED_PROPERTY_VALUE);
|
||||
assertThat(systemEnvironment.get(DISALLOWED_PROPERTY_NAME)).isNull();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
System.setSecurityManager(oldSecurityManager);
|
||||
}
|
||||
|
||||
EnvironmentTestUtils.getModifiableSystemEnvironment().remove(ALLOWED_PROPERTY_NAME);
|
||||
EnvironmentTestUtils.getModifiableSystemEnvironment().remove(DISALLOWED_PROPERTY_NAME);
|
||||
void getSystemEnvironment() {
|
||||
Map<String, Object> systemEnvironment = environment.getSystemEnvironment();
|
||||
assertThat(systemEnvironment).isNotNull();
|
||||
assertThat(System.getenv()).isSameAs(systemEnvironment);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,16 +17,13 @@
|
|||
package org.springframework.core.env;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SystemEnvironmentPropertySource}.
|
||||
*
|
||||
|
|
@ -148,30 +145,4 @@ class SystemEnvironmentPropertySourceTests {
|
|||
assertThat(ps.getProperty("A.hyphen-KEY")).isEqualTo("a_hyphen_value");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("serial")
|
||||
void withSecurityConstraints() throws Exception {
|
||||
envMap = new HashMap<String, Object>() {
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return new HashSet<>(super.keySet());
|
||||
}
|
||||
};
|
||||
envMap.put("A_KEY", "a_value");
|
||||
|
||||
ps = new SystemEnvironmentPropertySource("sysEnv", envMap) {
|
||||
@Override
|
||||
protected boolean isSecurityManagerPresent() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(ps.containsProperty("A_KEY")).isEqualTo(true);
|
||||
assertThat(ps.getProperty("A_KEY")).isEqualTo("a_value");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -33,8 +33,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link StreamUtils}.
|
||||
|
|
@ -57,53 +55,47 @@ class StreamUtilsTests {
|
|||
|
||||
@Test
|
||||
void copyToByteArray() throws Exception {
|
||||
InputStream inputStream = spy(new ByteArrayInputStream(bytes));
|
||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
||||
byte[] actual = StreamUtils.copyToByteArray(inputStream);
|
||||
assertThat(actual).isEqualTo(bytes);
|
||||
verify(inputStream, never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void copyToString() throws Exception {
|
||||
Charset charset = Charset.defaultCharset();
|
||||
InputStream inputStream = spy(new ByteArrayInputStream(string.getBytes(charset)));
|
||||
InputStream inputStream = new ByteArrayInputStream(string.getBytes(charset));
|
||||
String actual = StreamUtils.copyToString(inputStream, charset);
|
||||
assertThat(actual).isEqualTo(string);
|
||||
verify(inputStream, never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void copyBytes() throws Exception {
|
||||
ByteArrayOutputStream out = spy(new ByteArrayOutputStream());
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamUtils.copy(bytes, out);
|
||||
assertThat(out.toByteArray()).isEqualTo(bytes);
|
||||
verify(out, never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void copyString() throws Exception {
|
||||
Charset charset = Charset.defaultCharset();
|
||||
ByteArrayOutputStream out = spy(new ByteArrayOutputStream());
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamUtils.copy(string, charset, out);
|
||||
assertThat(out.toByteArray()).isEqualTo(string.getBytes(charset));
|
||||
verify(out, never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void copyStream() throws Exception {
|
||||
ByteArrayOutputStream out = spy(new ByteArrayOutputStream());
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamUtils.copy(new ByteArrayInputStream(bytes), out);
|
||||
assertThat(out.toByteArray()).isEqualTo(bytes);
|
||||
verify(out, never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void copyRange() throws Exception {
|
||||
ByteArrayOutputStream out = spy(new ByteArrayOutputStream());
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
StreamUtils.copyRange(new ByteArrayInputStream(bytes), out, 0, 100);
|
||||
byte[] range = Arrays.copyOfRange(bytes, 0, 101);
|
||||
assertThat(out.toByteArray()).isEqualTo(range);
|
||||
verify(out, never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.core.testfixture.env;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
|
||||
/**
|
||||
* Test utilities for {@link StandardEnvironment}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class EnvironmentTestUtils {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, String> getModifiableSystemEnvironment() {
|
||||
// for os x / linux
|
||||
Class<?>[] classes = Collections.class.getDeclaredClasses();
|
||||
Map<String, String> env = System.getenv();
|
||||
for (Class<?> cl : classes) {
|
||||
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
|
||||
try {
|
||||
Field field = cl.getDeclaredField("m");
|
||||
field.setAccessible(true);
|
||||
Object obj = field.get(env);
|
||||
if (obj != null && obj.getClass().getName().equals("java.lang.ProcessEnvironment$StringEnvironment")) {
|
||||
return (Map<String, String>) obj;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for windows
|
||||
Class<?> processEnvironmentClass;
|
||||
try {
|
||||
processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
try {
|
||||
Field theCaseInsensitiveEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
|
||||
theCaseInsensitiveEnvironmentField.setAccessible(true);
|
||||
Object obj = theCaseInsensitiveEnvironmentField.get(null);
|
||||
return (Map<String, String>) obj;
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
// do nothing
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
try {
|
||||
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theEnvironment");
|
||||
theEnvironmentField.setAccessible(true);
|
||||
Object obj = theEnvironmentField.get(null);
|
||||
return (Map<String, String>) obj;
|
||||
}
|
||||
catch (NoSuchFieldException ex) {
|
||||
// do nothing
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -21,8 +21,6 @@ import java.io.IOException;
|
|||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
|
|
@ -31,7 +29,7 @@ public class MockHttpOutputMessage implements HttpOutputMessage {
|
|||
|
||||
private final HttpHeaders headers = new HttpHeaders();
|
||||
|
||||
private final ByteArrayOutputStream body = spy(new ByteArrayOutputStream());
|
||||
private final ByteArrayOutputStream body = new ByteArrayOutputStream();
|
||||
|
||||
private boolean headersWritten = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -48,8 +48,6 @@ import org.springframework.util.LinkedMultiValueMap;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
|
||||
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA;
|
||||
import static org.springframework.http.MediaType.MULTIPART_MIXED;
|
||||
|
|
@ -226,10 +224,9 @@ public class FormHttpMessageConverterTests {
|
|||
item = items.get(5);
|
||||
assertThat(item.getFieldName()).isEqualTo("xml");
|
||||
assertThat(item.getContentType()).isEqualTo("text/xml");
|
||||
verify(outputMessage.getBody(), never()).close();
|
||||
}
|
||||
|
||||
@Test // SPR-13309
|
||||
@Test // SPR-13309
|
||||
public void writeMultipartOrder() throws Exception {
|
||||
MyBean myBean = new MyBean();
|
||||
myBean.setString("foo");
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public class StringHttpMessageConverterTests {
|
|||
assertThat(headers.getAcceptCharset().isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test // gh-24123
|
||||
@Test // gh-24123
|
||||
public void writeJson() throws IOException {
|
||||
String body = "{\"føø\":\"bår\"}";
|
||||
this.converter.write(body, MediaType.APPLICATION_JSON, this.outputMessage);
|
||||
|
|
@ -114,7 +114,7 @@ public class StringHttpMessageConverterTests {
|
|||
assertThat(headers.getAcceptCharset().isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test // gh-25328
|
||||
@Test // gh-25328
|
||||
public void writeJsonApi() throws IOException {
|
||||
String body = "{\"føø\":\"bår\"}";
|
||||
MediaType contentType = new MediaType("application", "vnd.api.v1+json");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -47,8 +47,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.assertj.core.api.Assertions.within;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Jackson 2.x converter tests.
|
||||
|
|
@ -188,7 +186,6 @@ public class MappingJackson2HttpMessageConverterTests {
|
|||
assertThat(result.contains("\"bool\":true")).isTrue();
|
||||
assertThat(result.contains("\"bytes\":\"AQI=\"")).isTrue();
|
||||
assertThat(outputMessage.getHeaders().getContentType()).as("Invalid content-type").isEqualTo(MediaType.APPLICATION_JSON);
|
||||
verify(outputMessage.getBody(), never()).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -51,13 +51,13 @@ public class ServletRequestAttributesTests {
|
|||
|
||||
|
||||
@Test
|
||||
public void ctorRejectsNullArg() throws Exception {
|
||||
public void ctorRejectsNullArg() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new ServletRequestAttributes(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setRequestScopedAttribute() throws Exception {
|
||||
public void setRequestScopedAttribute() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
ServletRequestAttributes attrs = new ServletRequestAttributes(request);
|
||||
attrs.setAttribute(KEY, VALUE, RequestAttributes.SCOPE_REQUEST);
|
||||
|
|
@ -66,7 +66,7 @@ public class ServletRequestAttributesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void setRequestScopedAttributeAfterCompletion() throws Exception {
|
||||
public void setRequestScopedAttributeAfterCompletion() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
ServletRequestAttributes attrs = new ServletRequestAttributes(request);
|
||||
request.close();
|
||||
|
|
@ -75,7 +75,7 @@ public class ServletRequestAttributesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void setSessionScopedAttribute() throws Exception {
|
||||
public void setSessionScopedAttribute() {
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
session.setAttribute(KEY, VALUE);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
|
@ -86,7 +86,7 @@ public class ServletRequestAttributesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void setSessionScopedAttributeAfterCompletion() throws Exception {
|
||||
public void setSessionScopedAttributeAfterCompletion() {
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
session.setAttribute(KEY, VALUE);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
|
@ -100,7 +100,7 @@ public class ServletRequestAttributesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void getSessionScopedAttributeDoesNotForceCreationOfSession() throws Exception {
|
||||
public void getSessionScopedAttributeDoesNotForceCreationOfSession() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
|
||||
ServletRequestAttributes attrs = new ServletRequestAttributes(request);
|
||||
|
|
@ -110,7 +110,7 @@ public class ServletRequestAttributesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void removeSessionScopedAttribute() throws Exception {
|
||||
public void removeSessionScopedAttribute() {
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
session.setAttribute(KEY, VALUE);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
|
@ -122,7 +122,7 @@ public class ServletRequestAttributesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void removeSessionScopedAttributeDoesNotForceCreationOfSession() throws Exception {
|
||||
public void removeSessionScopedAttributeDoesNotForceCreationOfSession() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
|
||||
ServletRequestAttributes attrs = new ServletRequestAttributes(request);
|
||||
|
|
@ -131,7 +131,7 @@ public class ServletRequestAttributesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void updateAccessedAttributes() throws Exception {
|
||||
public void updateAccessedAttributes() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpSession session = mock(HttpSession.class);
|
||||
given(request.getSession(anyBoolean())).willReturn(session);
|
||||
|
|
@ -153,7 +153,7 @@ public class ServletRequestAttributesTests {
|
|||
|
||||
@Test
|
||||
public void skipImmutableCharacter() {
|
||||
doSkipImmutableValue(new Character('x'));
|
||||
doSkipImmutableValue(Character.valueOf('x'));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue