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