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.service.UserLocalServiceUtil;
027 import com.liferay.portal.util.ClassLoaderUtil;
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 ClassLoaderUtil.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[] urlsExcludes = StringUtil.split(
172 properties.getProperty("urls.excludes"));
173
174 if ((urlsExcludes.length > 0) &&
175 (Wildcard.matchOne(requestURI, urlsExcludes) > -1)) {
176
177 return false;
178 }
179
180 String[] urlsIncludes = StringUtil.split(
181 properties.getProperty("urls.includes"));
182
183 if (urlsIncludes.length == 0) {
184 Class<?> authVerifierClass = authVerifier.getClass();
185
186 _log.error(
187 "Auth verifier " + authVerifierClass.getName() +
188 " does not have any URLs configured");
189
190 return false;
191 }
192
193 return Wildcard.matchOne(requestURI, urlsIncludes) > -1;
194 }
195
196 private AuthVerifierConfiguration _mergeAuthVerifierConfiguration(
197 AuthVerifierConfiguration authVerifierConfiguration,
198 AccessControlContext accessControlContext) {
199
200 Map<String, Object> settings = accessControlContext.getSettings();
201
202 String authVerifierSettingsKey = getAuthVerifierPropertyName(
203 authVerifierConfiguration.getAuthVerifierClassName());
204
205 boolean merge = false;
206
207 Set<String> settingsKeys = settings.keySet();
208
209 Iterator<String> iterator = settingsKeys.iterator();
210
211 while (iterator.hasNext() && !merge) {
212 String settingsKey = iterator.next();
213
214 if (settingsKey.startsWith(authVerifierSettingsKey)) {
215 if (settings.get(settingsKey) instanceof String) {
216 merge = true;
217 }
218 }
219 }
220
221 if (!merge) {
222 return authVerifierConfiguration;
223 }
224
225 AuthVerifierConfiguration mergedAuthVerifierConfiguration =
226 new AuthVerifierConfiguration();
227
228 mergedAuthVerifierConfiguration.setAuthVerifier(
229 authVerifierConfiguration.getAuthVerifier());
230
231 Properties mergedProperties = new Properties(
232 authVerifierConfiguration.getProperties());
233
234 for (String settingsKey : settings.keySet()) {
235 if (settingsKey.startsWith(authVerifierSettingsKey)) {
236 Object settingsValue = settings.get(settingsKey);
237
238 if (settingsValue instanceof String) {
239 String propertiesKey = settingsKey.substring(
240 authVerifierSettingsKey.length());
241
242 mergedProperties.setProperty(
243 propertiesKey, (String)settingsValue);
244 }
245 }
246 }
247
248 mergedAuthVerifierConfiguration.setProperties(mergedProperties);
249
250 return mergedAuthVerifierConfiguration;
251 }
252
253 private Map<String, Object> _mergeSettings(
254 Properties properties, Map<String, Object> settings) {
255
256 Map<String, Object> mergedSettings = new HashMap<String, Object>(
257 settings);
258
259 if (properties != null) {
260 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
261 mergedSettings.put((String)entry.getKey(), entry.getValue());
262 }
263 }
264
265 return mergedSettings;
266 }
267
268 private void _register(
269 AuthVerifierConfiguration authVerifierConfiguration) {
270
271 if (authVerifierConfiguration == null) {
272 throw new IllegalArgumentException(
273 "Auth verifier configuration is null");
274 }
275
276 if (authVerifierConfiguration.getAuthVerifier() == null) {
277 throw new IllegalArgumentException("Auth verifier is null");
278 }
279
280 if (authVerifierConfiguration.getAuthVerifierClassName() == null) {
281 throw new IllegalArgumentException("Class name is null");
282 }
283
284 if (authVerifierConfiguration.getProperties() == null) {
285 throw new IllegalArgumentException("Properties is null");
286 }
287
288 _authVerifierConfigurations.add(0, authVerifierConfiguration);
289 }
290
291 private void _unregister(
292 AuthVerifierConfiguration authVerifierConfiguration) {
293
294 if (authVerifierConfiguration == null) {
295 throw new IllegalArgumentException(
296 "Auth verifier configuration is null");
297 }
298
299 _authVerifierConfigurations.remove(authVerifierConfiguration);
300 }
301
302 private AuthVerifierResult _verifyRequest(
303 AccessControlContext accessControlContext)
304 throws PortalException, SystemException {
305
306 if (accessControlContext == null) {
307 throw new IllegalArgumentException(
308 "Access control context is null");
309 }
310
311 List<AuthVerifierConfiguration> authVerifierConfigurations =
312 _getAuthVerifierConfigurations(accessControlContext);
313
314 for (AuthVerifierConfiguration authVerifierConfiguration :
315 authVerifierConfigurations) {
316
317 AuthVerifierResult authVerifierResult = null;
318
319 AuthVerifier authVerifier =
320 authVerifierConfiguration.getAuthVerifier();
321
322 Properties properties = authVerifierConfiguration.getProperties();
323
324 try {
325 authVerifierResult = authVerifier.verify(
326 accessControlContext, properties);
327 }
328 catch (Exception e) {
329 if (_log.isDebugEnabled()) {
330 Class<?> authVerifierClass = authVerifier.getClass();
331
332 _log.debug("Skipping " + authVerifierClass.getName(), e);
333 }
334
335 continue;
336 }
337
338 if (authVerifierResult == null) {
339 Class<?> authVerifierClass = authVerifier.getClass();
340
341 _log.error(
342 "Auth verifier " + authVerifierClass.getName() +
343 " did not return an auth verifier result");
344
345 continue;
346 }
347
348 if (authVerifierResult.getState() !=
349 AuthVerifierResult.State.NOT_APPLICABLE) {
350
351 Map<String, Object> settings = _mergeSettings(
352 properties, authVerifierResult.getSettings());
353
354 settings.put(AUTH_TYPE, authVerifier.getAuthType());
355
356 authVerifierResult.setSettings(settings);
357
358 return authVerifierResult;
359 }
360 }
361
362 return _createGuestVerificationResult(accessControlContext);
363 }
364
365 private static Log _log = LogFactoryUtil.getLog(AuthVerifierPipeline.class);
366
367 private static AuthVerifierPipeline _instance = new AuthVerifierPipeline();
368
369 private List<AuthVerifierConfiguration> _authVerifierConfigurations;
370
371 }