001
014
015 package com.liferay.portal.security.auth;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.InstanceFactory;
022 import com.liferay.portal.kernel.util.PropsKeys;
023 import com.liferay.portal.kernel.util.PropsUtil;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
027 import com.liferay.portal.service.UserLocalServiceUtil;
028 import com.liferay.portal.util.PortalUtil;
029 import com.liferay.portal.util.PropsValues;
030
031 import java.util.ArrayList;
032 import java.util.HashMap;
033 import java.util.Iterator;
034 import java.util.List;
035 import java.util.Map;
036 import java.util.Properties;
037 import java.util.Set;
038 import java.util.concurrent.CopyOnWriteArrayList;
039
040 import javax.servlet.http.HttpServletRequest;
041
042 import jodd.util.Wildcard;
043
044
047 public class AuthVerifierPipeline {
048
049 public static final String AUTH_TYPE = "auth.type";
050
051 public static String getAuthVerifierPropertyName(String className) {
052 String simpleClassName = StringUtil.extractLast(
053 className, StringPool.PERIOD);
054
055 return PropsKeys.AUTH_VERIFIER.concat(simpleClassName).concat(
056 StringPool.PERIOD);
057 }
058
059 public static void register(
060 AuthVerifierConfiguration authVerifierConfiguration) {
061
062 _instance._register(authVerifierConfiguration);
063 }
064
065 public static void unregister(
066 AuthVerifierConfiguration authVerifierConfiguration) {
067
068 _instance._unregister(authVerifierConfiguration);
069 }
070
071 public static AuthVerifierResult verifyRequest(
072 AccessControlContext accessControlContext)
073 throws PortalException, SystemException {
074
075 return _instance._verifyRequest(accessControlContext);
076 }
077
078 private AuthVerifierPipeline() {
079 _initAuthVerifierConfigurations();
080 }
081
082 private AuthVerifierResult _createGuestVerificationResult(
083 AccessControlContext accessControlContext)
084 throws PortalException, SystemException {
085
086 AuthVerifierResult authVerifierResult = new AuthVerifierResult();
087
088 authVerifierResult.setState(AuthVerifierResult.State.SUCCESS);
089
090 HttpServletRequest request = accessControlContext.getRequest();
091
092 long companyId = PortalUtil.getCompanyId(request);
093
094 long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
095
096 authVerifierResult.setUserId(defaultUserId);
097
098 return authVerifierResult;
099 }
100
101 private List<AuthVerifierConfiguration> _getAuthVerifierConfigurations(
102 AccessControlContext accessControlContext) {
103
104 HttpServletRequest request = accessControlContext.getRequest();
105
106 List<AuthVerifierConfiguration> authVerifierConfigurations =
107 new ArrayList<AuthVerifierConfiguration>();
108
109 String requestURI = request.getRequestURI();
110
111 String contextPath = request.getContextPath();
112
113 requestURI = requestURI.substring(contextPath.length());
114
115 for (AuthVerifierConfiguration authVerifierConfiguration :
116 _authVerifierConfigurations) {
117
118 authVerifierConfiguration = _mergeAuthVerifierConfiguration(
119 authVerifierConfiguration, accessControlContext);
120
121 if (_isMatchingRequestURI(authVerifierConfiguration, requestURI)) {
122 authVerifierConfigurations.add(authVerifierConfiguration);
123 }
124 }
125
126 return authVerifierConfigurations;
127 }
128
129 private void _initAuthVerifierConfigurations() {
130 _authVerifierConfigurations =
131 new CopyOnWriteArrayList<AuthVerifierConfiguration>();
132
133 for (String authVerifierClassName :
134 PropsValues.AUTH_VERIFIER_PIPELINE) {
135
136 try {
137 AuthVerifierConfiguration authVerifierConfiguration =
138 new AuthVerifierConfiguration();
139
140 AuthVerifier authVerifier =
141 (AuthVerifier)InstanceFactory.newInstance(
142 PACLClassLoaderUtil.getPortalClassLoader(),
143 authVerifierClassName);
144
145 authVerifierConfiguration.setAuthVerifier(authVerifier);
146
147 authVerifierConfiguration.setAuthVerifierClassName(
148 authVerifierClassName);
149
150 Properties properties = PropsUtil.getProperties(
151 getAuthVerifierPropertyName(authVerifierClassName), true);
152
153 authVerifierConfiguration.setProperties(properties);
154
155 _authVerifierConfigurations.add(authVerifierConfiguration);
156 }
157 catch (Exception e) {
158 _log.error("Unable to initialize " + authVerifierClassName, e);
159 }
160 }
161 }
162
163 private boolean _isMatchingRequestURI(
164 AuthVerifierConfiguration authVerifierConfiguration,
165 String requestURI) {
166
167 AuthVerifier authVerifier = authVerifierConfiguration.getAuthVerifier();
168
169 Properties properties = authVerifierConfiguration.getProperties();
170
171 String[] urls = StringUtil.split(properties.getProperty("urls"));
172
173 if (urls.length == 0) {
174 Class<?> authVerifierClass = authVerifier.getClass();
175
176 _log.error(
177 "Auth verifier " + authVerifierClass.getName() +
178 " does not have any URLs configured");
179
180 return false;
181 }
182
183 return Wildcard.matchOne(requestURI, urls) > -1;
184 }
185
186 private AuthVerifierConfiguration _mergeAuthVerifierConfiguration(
187 AuthVerifierConfiguration authVerifierConfiguration,
188 AccessControlContext accessControlContext) {
189
190 Map<String, Object> settings = accessControlContext.getSettings();
191
192 String authVerifierSettingsKey = getAuthVerifierPropertyName(
193 authVerifierConfiguration.getAuthVerifierClassName());
194
195 boolean merge = false;
196
197 Set<String> settingsKeys = settings.keySet();
198
199 Iterator<String> iterator = settingsKeys.iterator();
200
201 while (iterator.hasNext() && !merge) {
202 String settingsKey = iterator.next();
203
204 if (settingsKey.startsWith(authVerifierSettingsKey)) {
205 if (settings.get(settingsKey) instanceof String) {
206 merge = true;
207 }
208 }
209 }
210
211 if (!merge) {
212 return authVerifierConfiguration;
213 }
214
215 AuthVerifierConfiguration mergedAuthVerifierConfiguration =
216 new AuthVerifierConfiguration();
217
218 mergedAuthVerifierConfiguration.setAuthVerifier(
219 authVerifierConfiguration.getAuthVerifier());
220
221 Properties mergedProperties = new Properties(
222 authVerifierConfiguration.getProperties());
223
224 for (String settingsKey : settings.keySet()) {
225 if (settingsKey.startsWith(authVerifierSettingsKey)) {
226 Object settingsValue = settings.get(settingsKey);
227
228 if (settingsValue instanceof String) {
229 String propertiesKey = settingsKey.substring(
230 authVerifierSettingsKey.length());
231
232 mergedProperties.setProperty(
233 propertiesKey, (String)settingsValue);
234 }
235
236 }
237 }
238
239 mergedAuthVerifierConfiguration.setProperties(mergedProperties);
240
241 return mergedAuthVerifierConfiguration;
242 }
243
244 private Map<String, Object> _mergeSettings(
245 Properties properties, Map<String, Object> settings) {
246
247 Map<String, Object> mergedSettings = new HashMap<String, Object>(
248 settings);
249
250 if (properties != null) {
251 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
252 mergedSettings.put((String)entry.getKey(), entry.getValue());
253 }
254 }
255
256 return mergedSettings;
257 }
258
259 private void _register(
260 AuthVerifierConfiguration authVerifierConfiguration) {
261
262 if (authVerifierConfiguration == null) {
263 throw new IllegalArgumentException(
264 "Auth verifier configuration is null");
265 }
266
267 if (authVerifierConfiguration.getAuthVerifier() == null) {
268 throw new IllegalArgumentException("Auth verifier is null");
269 }
270
271 if (authVerifierConfiguration.getAuthVerifierClassName() == null) {
272 throw new IllegalArgumentException("Class name is null");
273 }
274
275 if (authVerifierConfiguration.getProperties() == null) {
276 throw new IllegalArgumentException("Properties is null");
277 }
278
279 _authVerifierConfigurations.add(0, authVerifierConfiguration);
280 }
281
282 private void _unregister(
283 AuthVerifierConfiguration authVerifierConfiguration) {
284
285 if (authVerifierConfiguration == null) {
286 throw new IllegalArgumentException(
287 "Auth verifier configuration is null");
288 }
289
290 _authVerifierConfigurations.remove(authVerifierConfiguration);
291 }
292
293 private AuthVerifierResult _verifyRequest(
294 AccessControlContext accessControlContext)
295 throws PortalException, SystemException {
296
297 if (accessControlContext == null) {
298 throw new IllegalArgumentException(
299 "Access control context is null");
300 }
301
302 List<AuthVerifierConfiguration> authVerifierConfigurations =
303 _getAuthVerifierConfigurations(accessControlContext);
304
305 for (AuthVerifierConfiguration authVerifierConfiguration :
306 authVerifierConfigurations) {
307
308 AuthVerifierResult authVerifierResult = null;
309
310 AuthVerifier authVerifier =
311 authVerifierConfiguration.getAuthVerifier();
312
313 Properties properties = authVerifierConfiguration.getProperties();
314
315 try {
316 authVerifierResult = authVerifier.verify(
317 accessControlContext, properties);
318 }
319 catch (Exception e) {
320 Class<?> authVerifierClass = authVerifier.getClass();
321
322 _log.error("Skipping " + authVerifierClass.getName(), e);
323
324 continue;
325 }
326
327 if (authVerifierResult == null) {
328 Class<?> authVerifierClass = authVerifier.getClass();
329
330 _log.error(
331 "Auth verifier " + authVerifierClass.getName() +
332 " did not return an auth verifier result");
333
334 continue;
335 }
336
337 if (authVerifierResult.getState() !=
338 AuthVerifierResult.State.NOT_APPLICABLE) {
339
340 Map<String, Object> settings = _mergeSettings(
341 properties, authVerifierResult.getSettings());
342
343 settings.put(AUTH_TYPE, authVerifier.getAuthType());
344
345 authVerifierResult.setSettings(settings);
346
347 return authVerifierResult;
348 }
349 }
350
351 return _createGuestVerificationResult(accessControlContext);
352 }
353
354 private static Log _log = LogFactoryUtil.getLog(AuthVerifierPipeline.class);
355
356 private static AuthVerifierPipeline _instance = new AuthVerifierPipeline();
357
358 private List<AuthVerifierConfiguration> _authVerifierConfigurations;
359
360 }