/support/cas-server-support-throttle-mongo/src/main/java/org/apereo/cas/web/support/MongoDbThrottledSubmissionHandlerInterceptorAdapter.java

https://github.com/frett/cas · Java · 72 lines · 56 code · 10 blank · 6 comment · 0 complexity · 02c8b390f3d8f6233ad944b533622c9b MD5 · raw file

  1. package org.apereo.cas.web.support;
  2. import org.apereo.cas.audit.AuditTrailExecutionPlan;
  3. import org.apereo.cas.throttle.ThrottledRequestResponseHandler;
  4. import lombok.extern.slf4j.Slf4j;
  5. import lombok.val;
  6. import org.apereo.inspektr.audit.AuditActionContext;
  7. import org.apereo.inspektr.common.web.ClientInfoHolder;
  8. import org.springframework.data.domain.Sort;
  9. import org.springframework.data.mongodb.core.MongoTemplate;
  10. import org.springframework.data.mongodb.core.query.Criteria;
  11. import org.springframework.data.mongodb.core.query.Query;
  12. import javax.servlet.http.HttpServletRequest;
  13. import java.util.stream.Collectors;
  14. /**
  15. * Works in conjunction with a Mongo database to block attempts to dictionary attack users.
  16. *
  17. * @author Misagh Moayyed
  18. * @since 5.3.0
  19. */
  20. @Slf4j
  21. public class MongoDbThrottledSubmissionHandlerInterceptorAdapter extends AbstractInspektrAuditHandlerInterceptorAdapter {
  22. private final transient MongoTemplate mongoTemplate;
  23. private final String collectionName;
  24. public MongoDbThrottledSubmissionHandlerInterceptorAdapter(final int failureThreshold,
  25. final int failureRangeInSeconds,
  26. final String usernameParameter,
  27. final AuditTrailExecutionPlan auditTrailExecutionPlan,
  28. final MongoTemplate mongoTemplate,
  29. final String authenticationFailureCode,
  30. final String applicationCode, final String collectionName,
  31. final ThrottledRequestResponseHandler throttledRequestResponseHandler) {
  32. super(failureThreshold, failureRangeInSeconds, usernameParameter,
  33. authenticationFailureCode, auditTrailExecutionPlan, applicationCode,
  34. throttledRequestResponseHandler);
  35. this.mongoTemplate = mongoTemplate;
  36. this.collectionName = collectionName;
  37. }
  38. @Override
  39. public boolean exceedsThreshold(final HttpServletRequest request) {
  40. val clientInfo = ClientInfoHolder.getClientInfo();
  41. val remoteAddress = clientInfo.getClientIpAddress();
  42. val query = new Query()
  43. .addCriteria(Criteria.where("clientIpAddress").is(remoteAddress)
  44. .and("principal").is(getUsernameParameterFromRequest(request))
  45. .and("actionPerformed").is(getAuthenticationFailureCode())
  46. .and("applicationCode").is(getApplicationCode())
  47. .and("whenActionWasPerformed").gte(getFailureInRangeCutOffDate()));
  48. query.with(new Sort(Sort.Direction.DESC, "whenActionWasPerformed"));
  49. query.limit(2);
  50. query.fields().include("whenActionWasPerformed");
  51. LOGGER.debug("Executing MongoDb throttling query [{}]", query.toString());
  52. val failures = this.mongoTemplate.find(query, AuditActionContext.class, this.collectionName)
  53. .stream()
  54. .map(AuditActionContext::getWhenActionWasPerformed)
  55. .collect(Collectors.toList());
  56. return calculateFailureThresholdRateAndCompare(failures);
  57. }
  58. @Override
  59. public String getName() {
  60. return "MongoDbThrottle";
  61. }
  62. }