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