Search in sources :

Example 1 with SecuritySettings

use of org.thingsboard.server.common.data.security.model.SecuritySettings in project thingsboard by thingsboard.

the class DefaultSystemSecurityService method validateUserCredentials.

@Override
public void validateUserCredentials(TenantId tenantId, UserCredentials userCredentials, String username, String password) throws AuthenticationException {
    if (!encoder.matches(password, userCredentials.getPassword())) {
        int failedLoginAttempts = userService.onUserLoginIncorrectCredentials(tenantId, userCredentials.getUserId());
        SecuritySettings securitySettings = getSecuritySettings(tenantId);
        if (securitySettings.getMaxFailedLoginAttempts() != null && securitySettings.getMaxFailedLoginAttempts() > 0) {
            if (failedLoginAttempts > securitySettings.getMaxFailedLoginAttempts() && userCredentials.isEnabled()) {
                userService.setUserCredentialsEnabled(TenantId.SYS_TENANT_ID, userCredentials.getUserId(), false);
                if (StringUtils.isNoneBlank(securitySettings.getUserLockoutNotificationEmail())) {
                    try {
                        mailService.sendAccountLockoutEmail(username, securitySettings.getUserLockoutNotificationEmail(), securitySettings.getMaxFailedLoginAttempts());
                    } catch (ThingsboardException e) {
                        log.warn("Can't send email regarding user account [{}] lockout to provided email [{}]", username, securitySettings.getUserLockoutNotificationEmail(), e);
                    }
                }
                throw new LockedException("Authentication Failed. Username was locked due to security policy.");
            }
        }
        throw new BadCredentialsException("Authentication Failed. Username or Password not valid.");
    }
    if (!userCredentials.isEnabled()) {
        throw new DisabledException("User is not active");
    }
    userService.onUserLoginSuccessful(tenantId, userCredentials.getUserId());
    SecuritySettings securitySettings = self.getSecuritySettings(tenantId);
    if (isPositiveInteger(securitySettings.getPasswordPolicy().getPasswordExpirationPeriodDays())) {
        if ((userCredentials.getCreatedTime() + TimeUnit.DAYS.toMillis(securitySettings.getPasswordPolicy().getPasswordExpirationPeriodDays())) < System.currentTimeMillis()) {
            userCredentials = userService.requestExpiredPasswordReset(tenantId, userCredentials.getId());
            throw new UserPasswordExpiredException("User password expired!", userCredentials.getResetToken());
        }
    }
}
Also used : LockedException(org.springframework.security.authentication.LockedException) DisabledException(org.springframework.security.authentication.DisabledException) ThingsboardException(org.thingsboard.server.common.data.exception.ThingsboardException) UserPasswordExpiredException(org.thingsboard.server.service.security.exception.UserPasswordExpiredException) SecuritySettings(org.thingsboard.server.common.data.security.model.SecuritySettings) BadCredentialsException(org.springframework.security.authentication.BadCredentialsException)

Example 2 with SecuritySettings

use of org.thingsboard.server.common.data.security.model.SecuritySettings in project thingsboard by thingsboard.

the class DefaultSystemSecurityService method getSecuritySettings.

@Cacheable(cacheNames = SECURITY_SETTINGS_CACHE, key = "'securitySettings'")
@Override
public SecuritySettings getSecuritySettings(TenantId tenantId) {
    SecuritySettings securitySettings = null;
    AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, "securitySettings");
    if (adminSettings != null) {
        try {
            securitySettings = JacksonUtil.convertValue(adminSettings.getJsonValue(), SecuritySettings.class);
        } catch (Exception e) {
            throw new RuntimeException("Failed to load security settings!", e);
        }
    } else {
        securitySettings = new SecuritySettings();
        securitySettings.setPasswordPolicy(new UserPasswordPolicy());
        securitySettings.getPasswordPolicy().setMinimumLength(6);
    }
    return securitySettings;
}
Also used : SecuritySettings(org.thingsboard.server.common.data.security.model.SecuritySettings) BadCredentialsException(org.springframework.security.authentication.BadCredentialsException) LockedException(org.springframework.security.authentication.LockedException) DisabledException(org.springframework.security.authentication.DisabledException) AuthenticationException(org.springframework.security.core.AuthenticationException) UserPasswordExpiredException(org.thingsboard.server.service.security.exception.UserPasswordExpiredException) ThingsboardException(org.thingsboard.server.common.data.exception.ThingsboardException) DataValidationException(org.thingsboard.server.dao.exception.DataValidationException) UserPasswordPolicy(org.thingsboard.server.common.data.security.model.UserPasswordPolicy) AdminSettings(org.thingsboard.server.common.data.AdminSettings) Cacheable(org.springframework.cache.annotation.Cacheable)

Example 3 with SecuritySettings

use of org.thingsboard.server.common.data.security.model.SecuritySettings in project thingsboard by thingsboard.

the class DefaultSystemSecurityService method validatePassword.

@Override
public void validatePassword(TenantId tenantId, String password, UserCredentials userCredentials) throws DataValidationException {
    SecuritySettings securitySettings = self.getSecuritySettings(tenantId);
    UserPasswordPolicy passwordPolicy = securitySettings.getPasswordPolicy();
    List<Rule> passwordRules = new ArrayList<>();
    passwordRules.add(new LengthRule(passwordPolicy.getMinimumLength(), Integer.MAX_VALUE));
    if (isPositiveInteger(passwordPolicy.getMinimumUppercaseLetters())) {
        passwordRules.add(new CharacterRule(EnglishCharacterData.UpperCase, passwordPolicy.getMinimumUppercaseLetters()));
    }
    if (isPositiveInteger(passwordPolicy.getMinimumLowercaseLetters())) {
        passwordRules.add(new CharacterRule(EnglishCharacterData.LowerCase, passwordPolicy.getMinimumLowercaseLetters()));
    }
    if (isPositiveInteger(passwordPolicy.getMinimumDigits())) {
        passwordRules.add(new CharacterRule(EnglishCharacterData.Digit, passwordPolicy.getMinimumDigits()));
    }
    if (isPositiveInteger(passwordPolicy.getMinimumSpecialCharacters())) {
        passwordRules.add(new CharacterRule(EnglishCharacterData.Special, passwordPolicy.getMinimumSpecialCharacters()));
    }
    if (passwordPolicy.getAllowWhitespaces() != null && !passwordPolicy.getAllowWhitespaces()) {
        passwordRules.add(new WhitespaceRule());
    }
    PasswordValidator validator = new PasswordValidator(passwordRules);
    PasswordData passwordData = new PasswordData(password);
    RuleResult result = validator.validate(passwordData);
    if (!result.isValid()) {
        String message = String.join("\n", validator.getMessages(result));
        throw new DataValidationException(message);
    }
    if (userCredentials != null && isPositiveInteger(passwordPolicy.getPasswordReuseFrequencyDays())) {
        long passwordReuseFrequencyTs = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(passwordPolicy.getPasswordReuseFrequencyDays());
        User user = userService.findUserById(tenantId, userCredentials.getUserId());
        JsonNode additionalInfo = user.getAdditionalInfo();
        if (additionalInfo instanceof ObjectNode && additionalInfo.has(UserServiceImpl.USER_PASSWORD_HISTORY)) {
            JsonNode userPasswordHistoryJson = additionalInfo.get(UserServiceImpl.USER_PASSWORD_HISTORY);
            Map<String, String> userPasswordHistoryMap = JacksonUtil.convertValue(userPasswordHistoryJson, new TypeReference<>() {
            });
            for (Map.Entry<String, String> entry : userPasswordHistoryMap.entrySet()) {
                if (encoder.matches(password, entry.getValue()) && Long.parseLong(entry.getKey()) > passwordReuseFrequencyTs) {
                    throw new DataValidationException("Password was already used for the last " + passwordPolicy.getPasswordReuseFrequencyDays() + " days");
                }
            }
        }
    }
}
Also used : LengthRule(org.passay.LengthRule) DataValidationException(org.thingsboard.server.dao.exception.DataValidationException) User(org.thingsboard.server.common.data.User) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ArrayList(java.util.ArrayList) RuleResult(org.passay.RuleResult) JsonNode(com.fasterxml.jackson.databind.JsonNode) SecuritySettings(org.thingsboard.server.common.data.security.model.SecuritySettings) CharacterRule(org.passay.CharacterRule) WhitespaceRule(org.passay.WhitespaceRule) UserPasswordPolicy(org.thingsboard.server.common.data.security.model.UserPasswordPolicy) PasswordData(org.passay.PasswordData) PasswordValidator(org.passay.PasswordValidator) CharacterRule(org.passay.CharacterRule) WhitespaceRule(org.passay.WhitespaceRule) Rule(org.passay.Rule) LengthRule(org.passay.LengthRule) Map(java.util.Map)

Aggregations

SecuritySettings (org.thingsboard.server.common.data.security.model.SecuritySettings)3 BadCredentialsException (org.springframework.security.authentication.BadCredentialsException)2 DisabledException (org.springframework.security.authentication.DisabledException)2 LockedException (org.springframework.security.authentication.LockedException)2 ThingsboardException (org.thingsboard.server.common.data.exception.ThingsboardException)2 UserPasswordPolicy (org.thingsboard.server.common.data.security.model.UserPasswordPolicy)2 DataValidationException (org.thingsboard.server.dao.exception.DataValidationException)2 UserPasswordExpiredException (org.thingsboard.server.service.security.exception.UserPasswordExpiredException)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 CharacterRule (org.passay.CharacterRule)1 LengthRule (org.passay.LengthRule)1 PasswordData (org.passay.PasswordData)1 PasswordValidator (org.passay.PasswordValidator)1 Rule (org.passay.Rule)1 RuleResult (org.passay.RuleResult)1 WhitespaceRule (org.passay.WhitespaceRule)1 Cacheable (org.springframework.cache.annotation.Cacheable)1