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
249 mergedAuthVerifierConfiguration.setProperties(mergedProperties);
250
251 return mergedAuthVerifierConfiguration;
252 }
253
254 private Map<String, Object> _mergeSettings(
255 Properties properties, Map<String, Object> settings) {
256
257 Map<String, Object> mergedSettings = new HashMap<String, Object>(
258 settings);
259
260 if (properties != null) {
261 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
262 mergedSettings.put((String)entry.getKey(), entry.getValue());
263 }
264 }
265
266 return mergedSettings;
267 }
268
269 private void _register(
270 AuthVerifierConfiguration authVerifierConfiguration) {
271
272 if (authVerifierConfiguration == null) {
273 throw new IllegalArgumentException(
274 "Auth verifier configuration is null");
275 }
276
277 if (authVerifierConfiguration.getAuthVerifier() == null) {
278 throw new IllegalArgumentException("Auth verifier is null");
279 }
280
281 if (authVerifierConfiguration.getAuthVerifierClassName() == null) {
282 throw new IllegalArgumentException("Class name is null");
283 }
284
285 if (authVerifierConfiguration.getProperties() == null) {
286 throw new IllegalArgumentException("Properties is null");
287 }
288
289 _authVerifierConfigurations.add(0, authVerifierConfiguration);
290 }
291
292 private void _unregister(
293 AuthVerifierConfiguration authVerifierConfiguration) {
294
295 if (authVerifierConfiguration == null) {
296 throw new IllegalArgumentException(
297 "Auth verifier configuration is null");
298 }
299
300 _authVerifierConfigurations.remove(authVerifierConfiguration);
301 }
302
303 private AuthVerifierResult _verifyRequest(
304 AccessControlContext accessControlContext)
305 throws PortalException, SystemException {
306
307 if (accessControlContext == null) {
308 throw new IllegalArgumentException(
309 "Access control context is null");
310 }
311
312 List<AuthVerifierConfiguration> authVerifierConfigurations =
313 _getAuthVerifierConfigurations(accessControlContext);
314
315 for (AuthVerifierConfiguration authVerifierConfiguration :
316 authVerifierConfigurations) {
317
318 AuthVerifierResult authVerifierResult = null;
319
320 AuthVerifier authVerifier =
321 authVerifierConfiguration.getAuthVerifier();
322
323 Properties properties = authVerifierConfiguration.getProperties();
324
325 try {
326 authVerifierResult = authVerifier.verify(
327 accessControlContext, properties);
328 }
329 catch (Exception e) {
330 Class<?> authVerifierClass = authVerifier.getClass();
331
332 _log.error("Skipping " + authVerifierClass.getName(), e);
333
334 continue;
335 }
336
337 if (authVerifierResult == null) {
338 Class<?> authVerifierClass = authVerifier.getClass();
339
340 _log.error(
341 "Auth verifier " + authVerifierClass.getName() +
342 " did not return an auth verifier result");
343
344 continue;
345 }
346
347 if (authVerifierResult.getState() !=
348 AuthVerifierResult.State.NOT_APPLICABLE) {
349
350 Map<String, Object> settings = _mergeSettings(
351 properties, authVerifierResult.getSettings());
352
353 settings.put(AUTH_TYPE, authVerifier.getAuthType());
354
355 authVerifierResult.setSettings(settings);
356
357 return authVerifierResult;
358 }
359 }
360
361 return _createGuestVerificationResult(accessControlContext);
362 }
363
364 private static Log _log = LogFactoryUtil.getLog(AuthVerifierPipeline.class);
365
366 private static AuthVerifierPipeline _instance = new AuthVerifierPipeline();
367
368 private List<AuthVerifierConfiguration> _authVerifierConfigurations;
369
370 }