001
014
015 package com.liferay.portal.security.auth;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018 import com.liferay.portal.kernel.util.GetterUtil;
019 import com.liferay.portal.kernel.util.InstancePool;
020 import com.liferay.portal.kernel.util.ListUtil;
021 import com.liferay.portal.kernel.util.PropsKeys;
022 import com.liferay.portal.model.CompanyConstants;
023 import com.liferay.portal.util.PropsValues;
024 import com.liferay.registry.Filter;
025 import com.liferay.registry.Registry;
026 import com.liferay.registry.RegistryUtil;
027 import com.liferay.registry.ServiceReference;
028 import com.liferay.registry.ServiceRegistration;
029 import com.liferay.registry.ServiceTracker;
030 import com.liferay.registry.ServiceTrackerCustomizer;
031 import com.liferay.registry.collections.ServiceRegistrationMap;
032 import com.liferay.registry.util.StringPlus;
033
034 import java.util.HashMap;
035 import java.util.List;
036 import java.util.Map;
037
038
041 public class AuthPipeline {
042
043 public static int authenticateByEmailAddress(
044 String key, long companyId, String emailAddress, String password,
045 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
046 throws AuthException {
047
048 return _instance._authenticate(
049 key, companyId, emailAddress, password,
050 CompanyConstants.AUTH_TYPE_EA, headerMap, parameterMap);
051 }
052
053 public static int authenticateByScreenName(
054 String key, long companyId, String screenName, String password,
055 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
056 throws AuthException {
057
058 return _instance._authenticate(
059 key, companyId, screenName, password, CompanyConstants.AUTH_TYPE_SN,
060 headerMap, parameterMap);
061 }
062
063 public static int authenticateByUserId(
064 String key, long companyId, long userId, String password,
065 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
066 throws AuthException {
067
068 return _instance._authenticate(
069 key, companyId, String.valueOf(userId), password,
070 CompanyConstants.AUTH_TYPE_ID, headerMap, parameterMap);
071 }
072
073 public static void onFailureByEmailAddress(
074 String key, long companyId, String emailAddress,
075 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
076 throws AuthException {
077
078 _instance._onFailure(
079 key, companyId, emailAddress, CompanyConstants.AUTH_TYPE_EA,
080 headerMap, parameterMap);
081 }
082
083 public static void onFailureByScreenName(
084 String key, long companyId, String screenName,
085 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
086 throws AuthException {
087
088 _instance._onFailure(
089 key, companyId, screenName, CompanyConstants.AUTH_TYPE_SN,
090 headerMap, parameterMap);
091 }
092
093 public static void onFailureByUserId(
094 String key, long companyId, long userId,
095 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
096 throws AuthException {
097
098 _instance._onFailure(
099 key, companyId, String.valueOf(userId),
100 CompanyConstants.AUTH_TYPE_ID, headerMap, parameterMap);
101 }
102
103 public static void onMaxFailuresByEmailAddress(
104 String key, long companyId, String emailAddress,
105 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
106 throws AuthException {
107
108 onFailureByEmailAddress(
109 key, companyId, emailAddress, headerMap, parameterMap);
110 }
111
112 public static void onMaxFailuresByScreenName(
113 String key, long companyId, String screenName,
114 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
115 throws AuthException {
116
117 onFailureByScreenName(
118 key, companyId, screenName, headerMap, parameterMap);
119 }
120
121 public static void onMaxFailuresByUserId(
122 String key, long companyId, long userId,
123 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
124 throws AuthException {
125
126 onFailureByUserId(key, companyId, userId, headerMap, parameterMap);
127 }
128
129 public static void registerAuthenticator(
130 String key, Authenticator authenticator) {
131
132 _instance._registerAuthenticator(key, authenticator);
133 }
134
135 public static void registerAuthFailure(
136 String key, AuthFailure authFailure) {
137
138 _instance._registerAuthFailure(key, authFailure);
139 }
140
141 public static void unregisterAuthenticator(
142 String key, Authenticator authenticator) {
143
144 _instance._unregisterAuthenticator(authenticator);
145 }
146
147 public static void unregisterAuthFailure(
148 String key, AuthFailure authFailure) {
149
150 _instance._unregisterAuthFailure(authFailure);
151 }
152
153 private AuthPipeline() {
154 Registry registry = RegistryUtil.getRegistry();
155
156 Filter authFailureFilter = registry.getFilter(
157 "(&(key=*)(objectClass=" + AuthFailure.class.getName() + "))");
158
159 _authFailureServiceTracker = registry.trackServices(
160 authFailureFilter, new AuthFailureServiceTrackerCustomizer());
161
162 _authFailureServiceTracker.open();
163
164 _authFailures.put(PropsKeys.AUTH_FAILURE, new AuthFailure[0]);
165
166 for (String authFailureClassName : PropsValues.AUTH_FAILURE) {
167 AuthFailure authFailure = (AuthFailure)InstancePool.get(
168 authFailureClassName);
169
170 _registerAuthFailure(PropsKeys.AUTH_FAILURE, authFailure);
171 }
172
173 _authFailures.put(PropsKeys.AUTH_MAX_FAILURES, new AuthFailure[0]);
174
175 for (String authFailureClassName : PropsValues.AUTH_MAX_FAILURES) {
176 AuthFailure authFailure = (AuthFailure)InstancePool.get(
177 authFailureClassName);
178
179 _registerAuthFailure(PropsKeys.AUTH_MAX_FAILURES, authFailure);
180 }
181
182 Filter authenticatorFilter = registry.getFilter(
183 "(&(key=*)(objectClass=" + Authenticator.class.getName() + "))");
184
185 _authenticatorServiceTracker = registry.trackServices(
186 authenticatorFilter, new AuthenticatorServiceTrackerCustomizer());
187
188 _authenticatorServiceTracker.open();
189
190 _authenticators.put(PropsKeys.AUTH_PIPELINE_POST, new Authenticator[0]);
191
192 for (String authenticatorClassName : PropsValues.AUTH_PIPELINE_POST) {
193 Authenticator authenticator = (Authenticator)InstancePool.get(
194 authenticatorClassName);
195
196 _registerAuthenticator(PropsKeys.AUTH_PIPELINE_POST, authenticator);
197 }
198
199 _authenticators.put(PropsKeys.AUTH_PIPELINE_PRE, new Authenticator[0]);
200
201 for (String authenticatorClassName : PropsValues.AUTH_PIPELINE_PRE) {
202 Authenticator authenticator = (Authenticator)InstancePool.get(
203 authenticatorClassName);
204
205 _registerAuthenticator(PropsKeys.AUTH_PIPELINE_PRE, authenticator);
206 }
207 }
208
209 private int _authenticate(
210 String key, long companyId, String login, String password,
211 String authType, Map<String, String[]> headerMap,
212 Map<String, String[]> parameterMap)
213 throws AuthException {
214
215 boolean skipLiferayCheck = false;
216
217 Authenticator[] authenticators = _authenticators.get(key);
218
219 if (ArrayUtil.isEmpty(authenticators)) {
220 return Authenticator.SUCCESS;
221 }
222
223 for (Authenticator authenticator : authenticators) {
224 try {
225 int authResult = Authenticator.FAILURE;
226
227 if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
228 authResult = authenticator.authenticateByEmailAddress(
229 companyId, login, password, headerMap, parameterMap);
230 }
231 else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
232 authResult = authenticator.authenticateByScreenName(
233 companyId, login, password, headerMap, parameterMap);
234 }
235 else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
236 long userId = GetterUtil.getLong(login);
237
238 authResult = authenticator.authenticateByUserId(
239 companyId, userId, password, headerMap, parameterMap);
240 }
241
242 if (authResult == Authenticator.SKIP_LIFERAY_CHECK) {
243 skipLiferayCheck = true;
244 }
245 else if (authResult != Authenticator.SUCCESS) {
246 return authResult;
247 }
248 }
249 catch (AuthException ae) {
250 throw ae;
251 }
252 catch (Exception e) {
253 throw new AuthException(e);
254 }
255 }
256
257 if (skipLiferayCheck) {
258 return Authenticator.SKIP_LIFERAY_CHECK;
259 }
260
261 return Authenticator.SUCCESS;
262 }
263
264 private void _onFailure(
265 String key, long companyId, String login, String authType,
266 Map<String, String[]> headerMap, Map<String, String[]> parameterMap)
267 throws AuthException {
268
269 AuthFailure[] authFailures = _authFailures.get(key);
270
271 if (ArrayUtil.isEmpty(authFailures)) {
272 return;
273 }
274
275 for (AuthFailure authFailure : authFailures) {
276 try {
277 if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
278 authFailure.onFailureByEmailAddress(
279 companyId, login, headerMap, parameterMap);
280 }
281 else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
282 authFailure.onFailureByScreenName(
283 companyId, login, headerMap, parameterMap);
284 }
285 else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
286 long userId = GetterUtil.getLong(login);
287
288 authFailure.onFailureByUserId(
289 companyId, userId, headerMap, parameterMap);
290 }
291 }
292 catch (AuthException ae) {
293 throw ae;
294 }
295 catch (Exception e) {
296 throw new AuthException(e);
297 }
298 }
299 }
300
301 private void _registerAuthenticator(
302 String key, Authenticator authenticator) {
303
304 Registry registry = RegistryUtil.getRegistry();
305
306 Map<String, Object> properties = new HashMap<String, Object>();
307
308 properties.put("key", key);
309
310 ServiceRegistration<Authenticator> serviceRegistration =
311 registry.registerService(
312 Authenticator.class, authenticator, properties);
313
314 _authenticatorServiceRegistrations.put(
315 authenticator, serviceRegistration);
316 }
317
318 private void _registerAuthFailure(String key, AuthFailure authFailure) {
319 Registry registry = RegistryUtil.getRegistry();
320
321 Map<String, Object> properties = new HashMap<String, Object>();
322
323 properties.put("key", key);
324
325 ServiceRegistration<AuthFailure> serviceRegistration =
326 registry.registerService(
327 AuthFailure.class, authFailure, properties);
328
329 _authFailureServiceRegistrations.put(authFailure, serviceRegistration);
330 }
331
332 private void _unregisterAuthenticator(Authenticator authenticator) {
333 ServiceRegistration<Authenticator> serviceRegistration =
334 _authenticatorServiceRegistrations.remove(authenticator);
335
336 if (serviceRegistration != null) {
337 serviceRegistration.unregister();
338 }
339 }
340
341 private void _unregisterAuthFailure(AuthFailure authFailure) {
342 ServiceRegistration<AuthFailure> serviceRegistration =
343 _authFailureServiceRegistrations.remove(authFailure);
344
345 if (serviceRegistration != null) {
346 serviceRegistration.unregister();
347 }
348 }
349
350 private static final AuthPipeline _instance = new AuthPipeline();
351
352 private final Map<String, Authenticator[]> _authenticators =
353 new HashMap<String, Authenticator[]>();
354 private final Map<Authenticator, ServiceRegistration<Authenticator>>
355 _authenticatorServiceRegistrations =
356 new ServiceRegistrationMap<Authenticator>();
357 private final ServiceTracker<Authenticator, Authenticator>
358 _authenticatorServiceTracker;
359 private final Map<String, AuthFailure[]> _authFailures =
360 new HashMap<String, AuthFailure[]>();
361 private final Map<AuthFailure, ServiceRegistration<AuthFailure>>
362 _authFailureServiceRegistrations =
363 new ServiceRegistrationMap<AuthFailure>();
364 private final ServiceTracker<AuthFailure, AuthFailure>
365 _authFailureServiceTracker;
366
367 private class AuthenticatorServiceTrackerCustomizer
368 implements ServiceTrackerCustomizer<Authenticator, Authenticator> {
369
370 @Override
371 public Authenticator addingService(
372 ServiceReference<Authenticator> serviceReference) {
373
374 Registry registry = RegistryUtil.getRegistry();
375
376 Authenticator authenticator = registry.getService(serviceReference);
377
378 List<String> keys = StringPlus.asList(
379 serviceReference.getProperty("key"));
380
381 boolean added = false;
382
383 for (String key : keys) {
384 Authenticator[] authenticators = _authenticators.get(key);
385
386 if (authenticators == null) {
387 continue;
388 }
389
390 added = true;
391
392 authenticators = ArrayUtil.append(
393 authenticators, authenticator);
394
395 _authenticators.put(key, authenticators);
396 }
397
398 if (!added) {
399 return null;
400 }
401
402 return authenticator;
403 }
404
405 @Override
406 public void modifiedService(
407 ServiceReference<Authenticator> serviceReference,
408 Authenticator authenticator) {
409 }
410
411 @Override
412 public void removedService(
413 ServiceReference<Authenticator> serviceReference,
414 Authenticator authenticator) {
415
416 Registry registry = RegistryUtil.getRegistry();
417
418 registry.ungetService(serviceReference);
419
420 List<String> keys = StringPlus.asList(
421 serviceReference.getProperty("key"));
422
423 for (String key : keys) {
424 Authenticator[] authenticators = _authenticators.get(key);
425
426 if (authenticators == null) {
427 continue;
428 }
429
430 List<Authenticator> authenticatorsList = ListUtil.toList(
431 authenticators);
432
433 if (authenticatorsList.remove(authenticator)) {
434 _authenticators.put(
435 key,
436 authenticatorsList.toArray(
437 new Authenticator[authenticatorsList.size()]));
438 }
439 }
440 }
441
442 }
443
444 private class AuthFailureServiceTrackerCustomizer
445 implements ServiceTrackerCustomizer<AuthFailure, AuthFailure> {
446
447 @Override
448 public AuthFailure addingService(
449 ServiceReference<AuthFailure> serviceReference) {
450
451 Registry registry = RegistryUtil.getRegistry();
452
453 AuthFailure authFailure = registry.getService(serviceReference);
454
455 List<String> keys = StringPlus.asList(
456 serviceReference.getProperty("key"));
457
458 boolean added = false;
459
460 for (String key : keys) {
461 AuthFailure[] authFailures = _authFailures.get(key);
462
463 if (authFailures == null) {
464 continue;
465 }
466
467 added = true;
468
469 authFailures = ArrayUtil.append(authFailures, authFailure);
470
471 _authFailures.put(key, authFailures);
472 }
473
474 if (!added) {
475 return null;
476 }
477
478 return authFailure;
479 }
480
481 @Override
482 public void modifiedService(
483 ServiceReference<AuthFailure> serviceReference,
484 AuthFailure authFailure) {
485 }
486
487 @Override
488 public void removedService(
489 ServiceReference<AuthFailure> serviceReference,
490 AuthFailure authFailure) {
491
492 Registry registry = RegistryUtil.getRegistry();
493
494 registry.ungetService(serviceReference);
495
496 List<String> keys = StringPlus.asList(
497 serviceReference.getProperty("key"));
498
499 for (String key : keys) {
500 AuthFailure[] authFailures = _authFailures.get(key);
501
502 if (authFailures == null) {
503 continue;
504 }
505
506 List<AuthFailure> authFailuresList = ListUtil.fromArray(
507 authFailures);
508
509 if (authFailuresList.remove(authFailure)) {
510 _authFailures.put(
511 key,
512 authFailuresList.toArray(
513 new AuthFailure[authFailuresList.size()]));
514 }
515 }
516 }
517
518 }
519
520 }