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(key, authenticator);
145 }
146
147 public static void unregisterAuthFailure(
148 String key, AuthFailure authFailure) {
149
150 _instance._unregisterAuthFailure(key, 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(
333 String key, Authenticator authenticator) {
334
335 ServiceRegistration<Authenticator> serviceRegistration =
336 _authenticatorServiceRegistrations.remove(authenticator);
337
338 if (serviceRegistration != null) {
339 serviceRegistration.unregister();
340 }
341 }
342
343 private void _unregisterAuthFailure(String key, AuthFailure authFailure) {
344 ServiceRegistration<AuthFailure> serviceRegistration =
345 _authFailureServiceRegistrations.remove(authFailure);
346
347 if (serviceRegistration != null) {
348 serviceRegistration.unregister();
349 }
350 }
351
352 private static final AuthPipeline _instance = new AuthPipeline();
353
354 private final Map<String, Authenticator[]> _authenticators =
355 new HashMap<String, Authenticator[]>();
356 private final Map<Authenticator, ServiceRegistration<Authenticator>>
357 _authenticatorServiceRegistrations =
358 new ServiceRegistrationMap<Authenticator>();
359 private final ServiceTracker<Authenticator, Authenticator>
360 _authenticatorServiceTracker;
361 private final Map<String, AuthFailure[]> _authFailures =
362 new HashMap<String, AuthFailure[]>();
363 private final Map<AuthFailure, ServiceRegistration<AuthFailure>>
364 _authFailureServiceRegistrations =
365 new ServiceRegistrationMap<AuthFailure>();
366 private final ServiceTracker<AuthFailure, AuthFailure>
367 _authFailureServiceTracker;
368
369 private class AuthenticatorServiceTrackerCustomizer
370 implements ServiceTrackerCustomizer<Authenticator, Authenticator> {
371
372 @Override
373 public Authenticator addingService(
374 ServiceReference<Authenticator> serviceReference) {
375
376 Registry registry = RegistryUtil.getRegistry();
377
378 Authenticator authenticator = registry.getService(serviceReference);
379
380 List<String> keys = StringPlus.asList(
381 serviceReference.getProperty("key"));
382
383 boolean added = false;
384
385 for (String key : keys) {
386 Authenticator[] authenticators = _authenticators.get(key);
387
388 if (authenticators == null) {
389 continue;
390 }
391
392 added = true;
393
394 authenticators = ArrayUtil.append(
395 authenticators, authenticator);
396
397 _authenticators.put(key, authenticators);
398 }
399
400 if (!added) {
401 return null;
402 }
403
404 return authenticator;
405 }
406
407 @Override
408 public void modifiedService(
409 ServiceReference<Authenticator> serviceReference,
410 Authenticator authenticator) {
411 }
412
413 @Override
414 public void removedService(
415 ServiceReference<Authenticator> serviceReference,
416 Authenticator authenticator) {
417
418 Registry registry = RegistryUtil.getRegistry();
419
420 registry.ungetService(serviceReference);
421
422 List<String> keys = StringPlus.asList(
423 serviceReference.getProperty("key"));
424
425 for (String key : keys) {
426 Authenticator[] authenticators = _authenticators.get(key);
427
428 if (authenticators == null) {
429 continue;
430 }
431
432 List<Authenticator> authenticatorsList = ListUtil.toList(
433 authenticators);
434
435 if (authenticatorsList.remove(authenticator)) {
436 _authenticators.put(
437 key,
438 authenticatorsList.toArray(
439 new Authenticator[authenticatorsList.size()]));
440 }
441 }
442 }
443
444 }
445
446 private class AuthFailureServiceTrackerCustomizer
447 implements ServiceTrackerCustomizer<AuthFailure, AuthFailure> {
448
449 @Override
450 public AuthFailure addingService(
451 ServiceReference<AuthFailure> serviceReference) {
452
453 Registry registry = RegistryUtil.getRegistry();
454
455 AuthFailure authFailure = registry.getService(serviceReference);
456
457 List<String> keys = StringPlus.asList(
458 serviceReference.getProperty("key"));
459
460 boolean added = false;
461
462 for (String key : keys) {
463 AuthFailure[] authFailures = _authFailures.get(key);
464
465 if (authFailures == null) {
466 continue;
467 }
468
469 added = true;
470
471 authFailures = ArrayUtil.append(authFailures, authFailure);
472
473 _authFailures.put(key, authFailures);
474 }
475
476 if (!added) {
477 return null;
478 }
479
480 return authFailure;
481 }
482
483 @Override
484 public void modifiedService(
485 ServiceReference<AuthFailure> serviceReference,
486 AuthFailure authFailure) {
487 }
488
489 @Override
490 public void removedService(
491 ServiceReference<AuthFailure> serviceReference,
492 AuthFailure authFailure) {
493
494 Registry registry = RegistryUtil.getRegistry();
495
496 registry.ungetService(serviceReference);
497
498 List<String> keys = StringPlus.asList(
499 serviceReference.getProperty("key"));
500
501 for (String key : keys) {
502 AuthFailure[] authFailures = _authFailures.get(key);
503
504 if (authFailures == null) {
505 continue;
506 }
507
508 List<AuthFailure> authFailuresList = ListUtil.fromArray(
509 authFailures);
510
511 if (authFailuresList.remove(authFailure)) {
512 _authFailures.put(
513 key,
514 authFailuresList.toArray(
515 new AuthFailure[authFailuresList.size()]));
516 }
517 }
518 }
519
520 }
521
522 }