Exemple #1
0
  @Override
  public User save(final User user) {
    // 1. save clear password value before save
    String clearPwd = user.getClearPassword();

    // 2. save and flush to trigger entity validation
    User merged = super.save(user);
    entityManager().flush();

    // 3. set back the sole clear password value
    JPAUser.class.cast(merged).setClearPassword(clearPwd);

    // 4. enforce password and account policies
    try {
      enforcePolicies(merged);
    } catch (InvalidEntityException e) {
      entityManager().remove(merged);
      throw e;
    }

    roleDAO.refreshDynMemberships(merged);
    groupDAO.refreshDynMemberships(merged);

    return merged;
  }
  @PreAuthorize("isAnonymous() or hasRole('" + Entitlement.ANONYMOUS + "')")
  public SecurityQuestionTO read(final String username) {
    if (username == null) {
      throw new NotFoundException("Null username");
    }
    User user = userDAO.find(username);
    if (user == null) {
      throw new NotFoundException("User " + username);
    }

    if (user.getSecurityQuestion() == null) {
      LOG.error("Could not find security question for user '" + username + "'");

      throw new NotFoundException("Security question for user " + username);
    }

    return binder.getSecurityQuestionTO(user.getSecurityQuestion());
  }
Exemple #3
0
  @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
  @Override
  public Collection<ExternalResource> findAllResources(final User user) {
    Set<ExternalResource> result = new HashSet<>();
    result.addAll(user.getResources());
    for (Group group : findAllGroups(user)) {
      result.addAll(group.getResources());
    }

    return result;
  }
Exemple #4
0
  @Override
  protected void securityChecks(final User user) {
    // Allows anonymous (during self-registration) and self (during self-update) to read own user,
    // otherwise goes through security checks to see if required entitlements are owned
    if (!AuthContextUtils.getUsername().equals(anonymousUser)
        && !AuthContextUtils.getUsername().equals(user.getUsername())) {

      Set<String> authRealms =
          AuthContextUtils.getAuthorizations().get(StandardEntitlement.USER_READ);
      boolean authorized =
          IterableUtils.matchesAny(
              authRealms,
              new Predicate<String>() {

                @Override
                public boolean evaluate(final String realm) {
                  return user.getRealm().getFullPath().startsWith(realm);
                }
              });
      if (authRealms == null || authRealms.isEmpty() || !authorized) {
        throw new DelegatedAdministrationException(AnyTypeKind.USER, user.getKey());
      }
    }
  }
Exemple #5
0
  @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
  @Override
  public Collection<Group> findAllGroups(final User user) {
    return CollectionUtils.union(
        CollectionUtils.collect(
            user.getMemberships(),
            new Transformer<UMembership, Group>() {

              @Override
              public Group transform(final UMembership input) {
                return input.getRightEnd();
              }
            },
            new ArrayList<Group>()),
        findDynGroupMemberships(user));
  }
Exemple #6
0
  private List<AccountPolicy> getAccountPolicies(final User user) {
    List<AccountPolicy> policies = new ArrayList<>();

    // add resource policies
    for (ExternalResource resource : findAllResources(user)) {
      AccountPolicy policy = resource.getAccountPolicy();
      if (policy != null) {
        policies.add(policy);
      }
    }

    // add realm policies
    for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
      AccountPolicy policy = realm.getAccountPolicy();
      if (policy != null) {
        policies.add(policy);
      }
    }

    return policies;
  }
Exemple #7
0
 @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
 @Override
 public Collection<Role> findAllRoles(final User user) {
   return CollectionUtils.union(user.getRoles(), findDynRoleMemberships(user));
 }
Exemple #8
0
  @Transactional(readOnly = true)
  @Override
  public Pair<Boolean, Boolean> enforcePolicies(final User user) {
    // ------------------------------
    // Verify password policies
    // ------------------------------
    LOG.debug("Password Policy enforcement");

    try {
      int maxPPSpecHistory = 0;
      for (PasswordPolicy policy : getPasswordPolicies(user)) {
        if (user.getPassword() == null && !policy.isAllowNullPassword()) {
          throw new PasswordPolicyException("Password mandatory");
        }

        for (PasswordRuleConf ruleConf : policy.getRuleConfs()) {
          Class<? extends PasswordRule> ruleClass =
              implementationLookup.getPasswordRuleClass(ruleConf.getClass());
          if (ruleClass == null) {
            LOG.warn("Could not find matching password rule for {}", ruleConf.getClass());
          } else {
            // fetch (or create) rule
            PasswordRule rule;
            if (ApplicationContextProvider.getBeanFactory()
                .containsSingleton(ruleClass.getName())) {
              rule =
                  (PasswordRule)
                      ApplicationContextProvider.getBeanFactory().getSingleton(ruleClass.getName());
            } else {
              rule =
                  (PasswordRule)
                      ApplicationContextProvider.getBeanFactory()
                          .createBean(ruleClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
              ApplicationContextProvider.getBeanFactory()
                  .registerSingleton(ruleClass.getName(), rule);
            }

            // enforce rule
            rule.enforce(ruleConf, user);
          }
        }

        if (user.verifyPasswordHistory(user.getClearPassword(), policy.getHistoryLength())) {
          throw new PasswordPolicyException("Password value was used in the past: not allowed");
        }

        if (policy.getHistoryLength() > maxPPSpecHistory) {
          maxPPSpecHistory = policy.getHistoryLength();
        }
      }

      // update user's password history with encrypted password
      if (maxPPSpecHistory > 0 && user.getPassword() != null) {
        user.getPasswordHistory().add(user.getPassword());
      }
      // keep only the last maxPPSpecHistory items in user's password history
      if (maxPPSpecHistory < user.getPasswordHistory().size()) {
        for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
          user.getPasswordHistory().remove(i);
        }
      }
    } catch (Exception e) {
      LOG.error("Invalid password for {}", user, e);
      throw new InvalidEntityException(
          User.class, EntityViolationType.InvalidPassword, e.getMessage());
    } finally {
      // password has been validated, let's remove its clear version
      user.removeClearPassword();
    }

    // ------------------------------
    // Verify account policies
    // ------------------------------
    LOG.debug("Account Policy enforcement");

    boolean suspend = false;
    boolean propagateSuspension = false;
    try {
      if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
        throw new AccountPolicyException("Not allowed: " + user.getUsername());
      }

      for (AccountPolicy policy : getAccountPolicies(user)) {
        for (AccountRuleConf ruleConf : policy.getRuleConfs()) {
          Class<? extends AccountRule> ruleClass =
              implementationLookup.getAccountRuleClass(ruleConf.getClass());
          if (ruleClass == null) {
            LOG.warn("Could not find matching password rule for {}", ruleConf.getClass());
          } else {
            // fetch (or create) rule
            AccountRule rule;
            if (ApplicationContextProvider.getBeanFactory()
                .containsSingleton(ruleClass.getName())) {
              rule =
                  (AccountRule)
                      ApplicationContextProvider.getBeanFactory().getSingleton(ruleClass.getName());
            } else {
              rule =
                  (AccountRule)
                      ApplicationContextProvider.getBeanFactory()
                          .createBean(ruleClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
              ApplicationContextProvider.getBeanFactory()
                  .registerSingleton(ruleClass.getName(), rule);
            }

            // enforce rule
            rule.enforce(ruleConf, user);
          }
        }

        suspend |=
            user.getFailedLogins() != null
                && policy.getMaxAuthenticationAttempts() > 0
                && user.getFailedLogins() > policy.getMaxAuthenticationAttempts()
                && !user.isSuspended();
        propagateSuspension |= policy.isPropagateSuspension();
      }
    } catch (Exception e) {
      LOG.error("Invalid username for {}", user, e);
      throw new InvalidEntityException(
          User.class, EntityViolationType.InvalidUsername, e.getMessage());
    }

    return ImmutablePair.of(suspend, propagateSuspension);
  }
Exemple #9
0
  @SuppressWarnings("unchecked")
  public <T extends PolicySpec> T evaluate(final Policy policy, final Any<?, ?, ?> any) {
    if (policy == null) {
      return null;
    }

    T result = null;
    switch (policy.getType()) {
      case PASSWORD:
        PasswordPolicySpec ppSpec = policy.getSpecification(PasswordPolicySpec.class);
        PasswordPolicySpec evaluatedPPSpec = new PasswordPolicySpec();

        BeanUtils.copyProperties(ppSpec, evaluatedPPSpec, new String[] {"schemasNotPermitted"});

        for (String schema : ppSpec.getSchemasNotPermitted()) {
          PlainAttr attr = any.getPlainAttr(schema);
          if (attr != null) {
            List<String> values = attr.getValuesAsStrings();
            if (values != null && !values.isEmpty()) {
              evaluatedPPSpec.getWordsNotPermitted().add(values.get(0));
            }
          }
        }

        // Password history verification and update
        if (!(any instanceof User)) {
          LOG.error(
              "Cannot check previous passwords. instance is not user object: {}",
              any.getClass().getName());
          result = (T) evaluatedPPSpec;
          break;
        }
        User user = (User) any;
        if (user.verifyPasswordHistory(user.getClearPassword(), ppSpec.getHistoryLength())) {
          evaluatedPPSpec.getWordsNotPermitted().add(user.getClearPassword());
        }
        result = (T) evaluatedPPSpec;
        break;

      case ACCOUNT:
        final AccountPolicySpec spec = policy.getSpecification(AccountPolicySpec.class);
        final AccountPolicySpec accountPolicy = new AccountPolicySpec();

        BeanUtils.copyProperties(spec, accountPolicy, new String[] {"schemasNotPermitted"});

        for (String schema : spec.getSchemasNotPermitted()) {
          PlainAttr attr = any.getPlainAttr(schema);
          if (attr != null) {
            List<String> values = attr.getValuesAsStrings();
            if (values != null && !values.isEmpty()) {
              accountPolicy.getWordsNotPermitted().add(values.get(0));
            }
          }
        }

        result = (T) accountPolicy;
        break;

      case SYNC:
      default:
        result = null;
    }

    return result;
  }