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 public DoPrivilegedFactory() {
072 }
073
074 @Override
075 public Object getEarlyBeanReference(Object bean, String beanName)
076 throws BeansException {
077
078 if (_isWrap(bean, beanName)) {
079 _earlyBeanReferenceNames.add(beanName);
080 }
081
082 return bean;
083 }
084
085 @Override
086 public Object postProcessAfterInitialization(Object bean, String beanName)
087 throws BeansException {
088
089 if (SecurityManagerUtil.isPACLDisabled()) {
090 return bean;
091 }
092
093 if (!_isWrap(bean, beanName)) {
094 return bean;
095 }
096
097 if (isEarlyBeanReference(beanName)) {
098 if (_log.isDebugEnabled()) {
099 _log.debug("Postpone wrapping early reference of " + beanName);
100 }
101
102 return bean;
103 }
104
105 if (_log.isDebugEnabled()) {
106 Class<?> clazz = bean.getClass();
107
108 _log.debug(
109 "Wrapping calls to bean " + beanName + " of type " +
110 clazz + " with access controller checking");
111 }
112
113 return wrap(bean);
114 }
115
116 @Override
117 public Object postProcessBeforeInitialization(Object bean, String beanName)
118 throws BeansException {
119
120 return bean;
121 }
122
123 private boolean _isDoPrivileged(Class<?> beanClass) {
124 DoPrivileged doPrivileged = beanClass.getAnnotation(DoPrivileged.class);
125
126 while ((doPrivileged == null) &&
127 (beanClass = beanClass.getSuperclass()) != null) {
128
129 doPrivileged = beanClass.getAnnotation(DoPrivileged.class);
130 }
131
132 if (doPrivileged != null) {
133 return true;
134 }
135
136 return false;
137 }
138
139 private boolean _isFinderOrPersistence(String beanName) {
140 if (beanName.endsWith(_BEAN_NAME_SUFFIX_FINDER) ||
141 beanName.endsWith(_BEAN_NAME_SUFFIX_PERSISTENCE)) {
142
143 return true;
144 }
145
146 return false;
147 }
148
149 private boolean _isWrap(Object bean, String beanName) {
150 Class<?> clazz = bean.getClass();
151
152 if (_isDoPrivileged(clazz) || _isFinderOrPersistence(beanName)) {
153 return true;
154 }
155
156 return false;
157 }
158
159 private static final String _BEAN_NAME_SUFFIX_FINDER = "Finder";
160
161 private static final String _BEAN_NAME_SUFFIX_PERSISTENCE = "Persistence";
162
163 private static Log _log = LogFactoryUtil.getLog(DoPrivilegedFactory.class);
164
165 private static Set<String> _earlyBeanReferenceNames = new HashSet<String>();
166
167 private static class BeanPrivilegedAction <T>
168 implements PrivilegedAction<T> {
169
170 public BeanPrivilegedAction(T bean, Class<?>[] interfaces) {
171 _bean = bean;
172 _interfaces = ArrayUtil.append(interfaces, DoPrivilegedBean.class);
173 }
174
175 @Override
176 public T run() {
177 try {
178 return (T)ProxyUtil.newProxyInstance(
179 ClassLoaderUtil.getPortalClassLoader(), _interfaces,
180 new DoPrivilegedHandler(_bean));
181 }
182 catch (Exception e) {
183 if (_log.isWarnEnabled()) {
184 _log.warn(e, e);
185 }
186 }
187
188 return _bean;
189 }
190
191 private T _bean;
192 private Class<?>[] _interfaces;
193
194 }
195
196 }