/** * This method locks the accounts after a configured number of authentication failure attempts. * And unlocks accounts based on successful authentications. */ @Override public boolean doPostAuthenticate( String userName, boolean authenticated, UserStoreManager userStoreManager) throws UserStoreException { if (log.isDebugEnabled()) { log.debug("Post authenticator is called in IdentityMgtEventListener"); } IdentityMgtConfig config = IdentityMgtConfig.getInstance(); if (!config.isEnableAuthPolicy()) { return authenticated; } UserIdentityClaimsDO userIdentityDTO = module.load(userName, userStoreManager); if (userIdentityDTO == null) { userIdentityDTO = new UserIdentityClaimsDO(userName); } boolean userOTPEnabled = userIdentityDTO.getOneTimeLogin(); // One time password check if (authenticated && config.isAuthPolicyOneTimePasswordCheck() && (!userStoreManager.isReadOnly())) { // reset password of the user and notify user of the new password if (userOTPEnabled) { String password = UserIdentityManagementUtil.generateTemporaryPassword().toString(); userStoreManager.updateCredentialByAdmin(userName, password); // Get email user claim value String email = userStoreManager.getUserClaimValue( userName, UserCoreConstants.ClaimTypeURIs.EMAIL_ADDRESS, null); if (email == null) { throw new UserStoreException("No user email provided for user " + userName); } List<NotificationSendingModule> notificationModules = config.getNotificationSendingModules(); if (notificationModules != null) { NotificationDataDTO notificationData = new NotificationDataDTO(); NotificationData emailNotificationData = new NotificationData(); String emailTemplate = null; int tenantId = userStoreManager.getTenantId(); String firstName = null; try { firstName = Utils.getClaimFromUserStoreManager( userName, tenantId, "http://wso2.org/claims/givenname"); } catch (IdentityException e2) { throw new UserStoreException("Could not load user given name"); } emailNotificationData.setTagData("first-name", firstName); emailNotificationData.setTagData("user-name", userName); emailNotificationData.setTagData("otp-password", password); emailNotificationData.setSendTo(email); Config emailConfig = null; ConfigBuilder configBuilder = ConfigBuilder.getInstance(); try { emailConfig = configBuilder.loadConfiguration(ConfigType.EMAIL, StorageType.REGISTRY, tenantId); } catch (Exception e1) { throw new UserStoreException("Could not load the email template configuration"); } emailTemplate = emailConfig.getProperty("otp"); Notification emailNotification = null; try { emailNotification = NotificationBuilder.createNotification( "EMAIL", emailTemplate, emailNotificationData); } catch (Exception e) { throw new UserStoreException("Could not create the email notification"); } NotificationSender sender = new NotificationSender(); for (NotificationSendingModule notificationSendingModule : notificationModules) { if (IdentityMgtConfig.getInstance().isNotificationInternallyManaged()) { notificationSendingModule.setNotificationData(notificationData); notificationSendingModule.setNotification(emailNotification); sender.sendNotification(notificationSendingModule); notificationData.setNotificationSent(true); } } } else { throw new UserStoreException("No notification modules configured"); } } } // Password expire check. Not for OTP enabled users. if (authenticated && config.isAuthPolicyExpirePasswordCheck() && !userOTPEnabled && (!userStoreManager.isReadOnly())) { // TODO - password expire impl // Refactor adduser and change password api to stamp the time // Check user's expire time in the claim // if expired redirect to change password // else pass through /* long timestamp = userIdentityDTO.getPasswordTimeStamp(); // Only allow behavior to users with this claim. Intent bypass for admin? if (timestamp > 0) { Calendar passwordExpireTime = Calendar.getInstance(); passwordExpireTime.setTimeInMillis(timestamp); int expireDuration = config.getAuthPolicyPasswordExpireTime(); if (expireDuration > 0) { passwordExpireTime.add(Calendar.DATE, expireDuration); Calendar currentTime = Calendar.getInstance(); if (currentTime.compareTo(passwordExpireTime) > 0) { // password expired // set flag to redirect log.error("Password is expired ..........."); // throw new UserStoreException("Password is expired"); } } } */ } if (!authenticated && config.isAuthPolicyAccountLockOnFailure()) { userIdentityDTO.setFailAttempts(); // reading the max allowed #of failure attempts if (userIdentityDTO.getFailAttempts() >= config.getAuthPolicyMaxLoginAttempts()) { if (log.isDebugEnabled()) { log.debug( "User, " + userName + " has exceed the max failed login attempts. " + "User account would be locked"); } userIdentityDTO.setAccountLock(true); // lock time from the config int lockTime = IdentityMgtConfig.getInstance().getAuthPolicyLockingTime(); if (lockTime != 0) { userIdentityDTO.setUnlockTime(System.currentTimeMillis() + (lockTime * 60 * 1000)); } } try { module.store(userIdentityDTO, userStoreManager); } catch (IdentityException e) { throw new UserStoreException("Error while doPostAuthenticate", e); } } else { // if the account was locked due to account verification process, // the unlock the account and reset the number of failedAttempts if (userIdentityDTO.isAccountLocked() || userIdentityDTO.getFailAttempts() > 0) { userIdentityDTO.setAccountLock(false); userIdentityDTO.setFailAttempts(0); userIdentityDTO.setUnlockTime(0); try { module.store(userIdentityDTO, userStoreManager); } catch (IdentityException e) { throw new UserStoreException("Error while doPostAuthenticate", e); } } } return true; }