001
014
015 package com.liferay.portal.security.lang;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
020 import com.liferay.portal.kernel.util.AggregateClassLoader;
021 import com.liferay.portal.kernel.util.ArrayUtil;
022 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
023 import com.liferay.portal.kernel.util.ProxyUtil;
024 import com.liferay.portal.kernel.util.ReflectionUtil;
025
026 import java.security.AccessController;
027 import java.security.PrivilegedAction;
028
029 import java.util.HashSet;
030 import java.util.Set;
031
032 import org.springframework.beans.BeansException;
033 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
034 import org.springframework.context.ApplicationContext;
035 import org.springframework.context.ApplicationContextAware;
036
037
040 public class DoPrivilegedFactory
041 extends InstantiationAwareBeanPostProcessorAdapter
042 implements ApplicationContextAware {
043
044 public static boolean isEarlyBeanReference(String beanName) {
045 return _earlyBeanReferenceNames.contains(beanName);
046 }
047
048 public static <T> T wrap(T bean) {
049 Class<?> clazz = bean.getClass();
050
051 if (clazz.isPrimitive()) {
052 return bean;
053 }
054
055 Package pkg = clazz.getPackage();
056
057 if (pkg != null) {
058 String packageName = pkg.getName();
059
060 if (packageName.startsWith("java.")) {
061 return bean;
062 }
063 }
064
065 Class<?>[] interfaces = ReflectionUtil.getInterfaces(bean);
066
067 if (interfaces.length <= 0) {
068 return bean;
069 }
070
071 return AccessController.doPrivileged(
072 new BeanPrivilegedAction<T>(bean, interfaces));
073 }
074
075 @Override
076 public Object getEarlyBeanReference(Object bean, String beanName)
077 throws BeansException {
078
079 if (_isWrap(bean, beanName)) {
080 _earlyBeanReferenceNames.add(beanName);
081 }
082
083 return bean;
084 }
085
086 @Override
087 public Object postProcessAfterInitialization(Object bean, String beanName)
088 throws BeansException {
089
090 if (!SecurityManagerUtil.ENABLED) {
091 return bean;
092 }
093
094 if (!_isWrap(bean, beanName)) {
095 return bean;
096 }
097
098 if (isEarlyBeanReference(beanName)) {
099 if (_log.isDebugEnabled()) {
100 _log.debug("Postpone wrapping early reference of " + beanName);
101 }
102
103 return bean;
104 }
105
106 if (_log.isDebugEnabled()) {
107 Class<?> clazz = bean.getClass();
108
109 _log.debug(
110 "Wrapping calls to bean " + beanName + " of type " +
111 clazz + " with access controller checking");
112 }
113
114 return wrap(bean);
115 }
116
117 @Override
118 public Object postProcessBeforeInitialization(Object bean, String beanName)
119 throws BeansException {
120
121 return bean;
122 }
123
124 @Override
125 public void setApplicationContext(ApplicationContext applicationContext)
126 throws BeansException {
127
128 _classLoader = AggregateClassLoader.getAggregateClassLoader(
129 PortalClassLoaderUtil.getClassLoader(),
130 applicationContext.getClassLoader());
131 }
132
133 private boolean _isDoPrivileged(Class<?> beanClass) {
134 DoPrivileged doPrivileged = beanClass.getAnnotation(DoPrivileged.class);
135
136 while ((doPrivileged == null) &&
137 (beanClass = beanClass.getSuperclass()) != null) {
138
139 doPrivileged = beanClass.getAnnotation(DoPrivileged.class);
140 }
141
142 if (doPrivileged != null) {
143 return true;
144 }
145
146 return false;
147 }
148
149 private boolean _isFinderOrPersistence(String beanName) {
150 if (beanName.endsWith(_BEAN_NAME_SUFFIX_FINDER) ||
151 beanName.endsWith(_BEAN_NAME_SUFFIX_PERSISTENCE)) {
152
153 return true;
154 }
155
156 return false;
157 }
158
159 private boolean _isWrap(Object bean, String beanName) {
160 Class<?> clazz = bean.getClass();
161
162 if (_isDoPrivileged(clazz) || _isFinderOrPersistence(beanName)) {
163 return true;
164 }
165
166 return false;
167 }
168
169 private static final String _BEAN_NAME_SUFFIX_FINDER = "Finder";
170
171 private static final String _BEAN_NAME_SUFFIX_PERSISTENCE = "Persistence";
172
173 private static final Log _log = LogFactoryUtil.getLog(
174 DoPrivilegedFactory.class);
175
176 private static ClassLoader _classLoader =
177 DoPrivilegedFactory.class.getClassLoader();
178 private static final Set<String> _earlyBeanReferenceNames = new HashSet<>();
179
180 private static class BeanPrivilegedAction <T>
181 implements PrivilegedAction<T> {
182
183 public BeanPrivilegedAction(T bean, Class<?>[] interfaces) {
184 _bean = bean;
185 _interfaces = ArrayUtil.append(interfaces, DoPrivilegedBean.class);
186 }
187
188 @Override
189 public T run() {
190 try {
191 return (T)ProxyUtil.newProxyInstance(
192 _classLoader, _interfaces, new DoPrivilegedHandler(_bean));
193 }
194 catch (Exception e) {
195 if (_log.isWarnEnabled()) {
196 _log.warn(e, e);
197 }
198 }
199
200 return _bean;
201 }
202
203 private final T _bean;
204 private final Class<?>[] _interfaces;
205
206 }
207
208 }