def init(self, configurationAttributes):
        print "Basic (lock account). Initialization"

        self.invalidLoginCountAttribute = "oxCountInvalidLogin"
        if configurationAttributes.containsKey("invalid_login_count_attribute"):
            self.invalidLoginCountAttribute = configurationAttributes.get("invalid_login_count_attribute").getValue2()
        else:
            print "Basic (lock account). Initialization. Using default attribute"

        self.maximumInvalidLoginAttemps = 3
        if configurationAttributes.containsKey("maximum_invalid_login_attemps"):
            self.maximumInvalidLoginAttemps = StringHelper.toInteger(configurationAttributes.get("maximum_invalid_login_attemps").getValue2())
        else:
            print "Basic (lock account). Initialization. Using default number attempts"

        self.lockExpirationTime = 180
        if configurationAttributes.containsKey("lock_expiration_time"):
            self.lockExpirationTime = StringHelper.toInteger(configurationAttributes.get("lock_expiration_time").getValue2())
        else:
            print "Basic (lock account). Initialization. Using default lock expiration time"


        print "Basic (lock account). Initialized successfully. invalid_login_count_attribute: '%s', maximum_invalid_login_attemps: '%s', lock_expiration_time: '%s'" % (self.invalidLoginCountAttribute, self.maximumInvalidLoginAttemps, self.lockExpirationTime)

        return True   
    def init(self, customScript, configurationAttributes):
        print "Basic (lock account). Initialization"

        self.invalidLoginCountAttribute = "oxCountInvalidLogin"
        if configurationAttributes.containsKey(
                "invalid_login_count_attribute"):
            self.invalidLoginCountAttribute = configurationAttributes.get(
                "invalid_login_count_attribute").getValue2()
        else:
            print "Basic (lock account). Initialization. Using default attribute"

        self.maximumInvalidLoginAttemps = 3
        if configurationAttributes.containsKey(
                "maximum_invalid_login_attemps"):
            self.maximumInvalidLoginAttemps = StringHelper.toInteger(
                configurationAttributes.get(
                    "maximum_invalid_login_attemps").getValue2())
        else:
            print "Basic (lock account). Initialization. Using default number attempts"

        self.lockExpirationTime = 180
        if configurationAttributes.containsKey("lock_expiration_time"):
            self.lockExpirationTime = StringHelper.toInteger(
                configurationAttributes.get(
                    "lock_expiration_time").getValue2())
        else:
            print "Basic (lock account). Initialization. Using default lock expiration time"

        print "Basic (lock account). Initialized successfully. invalid_login_count_attribute: '%s', maximum_invalid_login_attemps: '%s', lock_expiration_time: '%s'" % (
            self.invalidLoginCountAttribute, self.maximumInvalidLoginAttemps,
            self.lockExpirationTime)

        return True
    def getCountAuthenticationSteps(self, configurationAttributes):
        identity = CdiUtil.bean(Identity)

        if identity.isSetWorkingParameter("otp_count_login_steps"):
            return StringHelper.toInteger("%s" % identity.getWorkingParameter("otp_count_login_steps"))
        else:
            return 2
Example #4
0
    def getCountAuthenticationSteps(self, configurationAttributes):
        identity = CdiUtil.bean(Identity)

        if identity.isSetWorkingParameter("otp_count_login_steps"):
            return StringHelper.toInteger("%s" % identity.getWorkingParameter("otp_count_login_steps"))
        else:
            return 2
Example #5
0
 def getCountAuthenticationSteps(self, configurationAttributes):
     print "U2F. getCountAuthenticationSteps called"
     # To do any operations we need the identity variables available
     steps = 1
     identity = CdiUtil.bean(Identity)
     if identity.isSetWorkingParameter("count_login_steps"):
         steps = StringHelper.toInteger(
             "%s" % identity.getWorkingParameter("count_login_steps"))
     print "U2F. getCountAuthenticationSteps returning %s" % steps
     return steps
    def init(self, configurationAttributes):
        print "Cert. Initialization"

        if not (configurationAttributes.containsKey("chain_cert_file_path")):
            print "Cert. Initialization. Property chain_cert_file_path is mandatory"
            return False

        if not (configurationAttributes.containsKey("map_user_cert")):
            print "Cert. Initialization. Property map_user_cert is mandatory"
            return False

        chain_cert_file_path = configurationAttributes.get("chain_cert_file_path").getValue2()

        self.chain_certs = CertUtil.loadX509CertificateFromFile(chain_cert_file_path)
        if self.chain_certs == None:
            print "Cert. Initialization. Failed to load chain certificates from '%s'" % chain_cert_file_path
            return False

        print "Cert. Initialization. Loaded '%d' chain certificates" % self.chain_certs.size()
        
        crl_max_response_size = 5 * 1024 * 1024  # 10Mb
        if configurationAttributes.containsKey("crl_max_response_size"):
            crl_max_response_size = StringHelper.toInteger(configurationAttributes.get("crl_max_response_size").getValue2(), crl_max_response_size)
            print "Cert. Initialization. CRL max response size is '%d'" % crl_max_response_size

        # Define array to order methods correctly
        self.validator_types = [ 'generic', 'path', 'ocsp', 'crl']
        self.validators = { 'generic' : [GenericCertificateVerifier(), False],
                            'path' : [PathCertificateVerifier(False), False],
                            'ocsp' : [OCSPCertificateVerifier(), False],
                            'crl' : [CRLCertificateVerifier(crl_max_response_size), False] }

        for type in self.validator_types:
            validator_param_name = "use_%s_validator" % type
            if configurationAttributes.containsKey(validator_param_name):
                validator_status = StringHelper.toBoolean(configurationAttributes.get(validator_param_name).getValue2(), False)
                self.validators[type][1] = validator_status

            print "Cert. Initialization. Validation method '%s' status: '%s'" % (type, self.validators[type][1])

        self.map_user_cert = StringHelper.toBoolean(configurationAttributes.get("map_user_cert").getValue2(), False)
        print "Cert. Initialization. map_user_cert: '%s'" % self.map_user_cert

        self.enabled_recaptcha = self.initRecaptcha(configurationAttributes)
        print "Cert. Initialization. enabled_recaptcha: '%s'" % self.enabled_recaptcha

        print "Cert. Initialized successfully"

        return True   
Example #7
0
    def init(self, customScript, configurationAttributes):
        print "Cert. Initialization"

        if not (configurationAttributes.containsKey("chain_cert_file_path")):
            print "Cert. Initialization. Property chain_cert_file_path is mandatory"
            return False

        if not (configurationAttributes.containsKey("map_user_cert")):
            print "Cert. Initialization. Property map_user_cert is mandatory"
            return False

        chain_cert_file_path = configurationAttributes.get("chain_cert_file_path").getValue2()

        self.chain_certs = CertUtil.loadX509CertificateFromFile(chain_cert_file_path)
        if self.chain_certs == None:
            print "Cert. Initialization. Failed to load chain certificates from '%s'" % chain_cert_file_path
            return False

        print "Cert. Initialization. Loaded '%d' chain certificates" % self.chain_certs.size()
        
        crl_max_response_size = 5 * 1024 * 1024  # 10Mb
        if configurationAttributes.containsKey("crl_max_response_size"):
            crl_max_response_size = StringHelper.toInteger(configurationAttributes.get("crl_max_response_size").getValue2(), crl_max_response_size)
            print "Cert. Initialization. CRL max response size is '%d'" % crl_max_response_size

        # Define array to order methods correctly
        self.validator_types = [ 'generic', 'path', 'ocsp', 'crl']
        self.validators = { 'generic' : [GenericCertificateVerifier(), False],
                            'path' : [PathCertificateVerifier(False), False],
                            'ocsp' : [OCSPCertificateVerifier(), False],
                            'crl' : [CRLCertificateVerifier(crl_max_response_size), False] }

        for type in self.validator_types:
            validator_param_name = "use_%s_validator" % type
            if configurationAttributes.containsKey(validator_param_name):
                validator_status = StringHelper.toBoolean(configurationAttributes.get(validator_param_name).getValue2(), False)
                self.validators[type][1] = validator_status

            print "Cert. Initialization. Validation method '%s' status: '%s'" % (type, self.validators[type][1])

        self.map_user_cert = StringHelper.toBoolean(configurationAttributes.get("map_user_cert").getValue2(), False)
        print "Cert. Initialization. map_user_cert: '%s'" % self.map_user_cert

        self.enabled_recaptcha = self.initRecaptcha(configurationAttributes)
        print "Cert. Initialization. enabled_recaptcha: '%s'" % self.enabled_recaptcha

        print "Cert. Initialized successfully"

        return True   
    def authenticate(self, configurationAttributes, requestParameters, step):
        authenticationService = CdiUtil.bean(AuthenticationService)

        if step == 1:
            print "Basic (lock account). Authenticate for step 1"
            facesMessages = CdiUtil.bean(FacesMessages)
            facesMessages.setKeepMessages()
            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()
            user_name = credentials.getUsername()
            user_password = credentials.getPassword()
            cacheService = CdiUtil.bean(CacheService)
            userService = CdiUtil.bean(UserService)

            logged_in = False
            if (StringHelper.isNotEmptyString(user_name)
                    and StringHelper.isNotEmptyString(user_password)):
                try:
                    logged_in = authenticationService.authenticate(
                        user_name, user_password)
                except AuthenticationException:
                    print "Basic (lock account). Authenticate. Failed to authenticate user '%s'" % user_name

            if logged_in:
                self.setUserAttributeValue(user_name,
                                           self.invalidLoginCountAttribute,
                                           StringHelper.toString(0))
            else:
                countInvalidLoginArributeValue = self.getUserAttributeValue(
                    user_name, self.invalidLoginCountAttribute)
                userSatus = self.getUserAttributeValue(user_name, "gluuStatus")
                print "Current user '%s' status is '%s'" % (user_name,
                                                            userSatus)

                countInvalidLogin = StringHelper.toInteger(
                    countInvalidLoginArributeValue, 0)

                if countInvalidLogin < self.maximumInvalidLoginAttemps:
                    countInvalidLogin = countInvalidLogin + 1
                    remainingAttempts = self.maximumInvalidLoginAttemps - countInvalidLogin

                    print "Remaining login count attempts '%s' for user '%s'" % (
                        remainingAttempts, user_name)

                    self.setUserAttributeValue(
                        user_name, self.invalidLoginCountAttribute,
                        StringHelper.toString(countInvalidLogin))
                    if remainingAttempts > 0 and userSatus == "active":
                        facesMessages.add(
                            FacesMessage.SEVERITY_INFO,
                            StringHelper.toString(remainingAttempts) +
                            " more attempt(s) before account is LOCKED!")

                if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and (
                    (userSatus == None) or (userSatus == "active")):
                    print "Basic (lock account). Locking '%s' for '%s' seconds" % (
                        user_name, self.lockExpirationTime)
                    self.lockUser(user_name)
                    return False

                if (countInvalidLogin >= self.maximumInvalidLoginAttemps
                    ) and userSatus == "inactive":
                    print "Basic (lock account). User '%s' is locked. Checking if we can unlock him" % user_name

                    unlock_and_authenticate = False

                    object_from_store = cacheService.get(
                        None, "lock_user_" + user_name)
                    if object_from_store == None:
                        # Object in cache was expired. We need to unlock user
                        print "Basic (lock account). User locking details for user '%s' not exists" % user_name
                        unlock_and_authenticate = True
                    else:
                        # Analyze object from cache
                        user_lock_details = json.loads(object_from_store)

                        user_lock_details_locked = user_lock_details['locked']
                        user_lock_details_created = user_lock_details[
                            'created']
                        user_lock_details_created_date = LocalDateTime.parse(
                            user_lock_details_created,
                            DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                        user_lock_details_created_diff = Duration.between(
                            user_lock_details_created_date,
                            LocalDateTime.now()).getSeconds()
                        print "Basic (lock account). Get user '%s' locking details. locked: '%s', Created: '%s', Difference in seconds: '%s'" % (
                            user_name, user_lock_details_locked,
                            user_lock_details_created,
                            user_lock_details_created_diff)

                        if user_lock_details_locked and user_lock_details_created_diff >= self.lockExpirationTime:
                            print "Basic (lock account). Unlocking user '%s' after lock expiration" % user_name
                            unlock_and_authenticate = True

                    if unlock_and_authenticate:
                        self.unLockUser(user_name)
                        self.setUserAttributeValue(
                            user_name, self.invalidLoginCountAttribute,
                            StringHelper.toString(0))
                        logged_in = authenticationService.authenticate(
                            user_name, user_password)
                        if not logged_in:
                            # Update number of attempts
                            self.setUserAttributeValue(
                                user_name, self.invalidLoginCountAttribute,
                                StringHelper.toString(1))
                            if self.maximumInvalidLoginAttemps == 1:
                                # Lock user if maximum count login attempts is 1
                                self.lockUser(user_name)
                                return False

            return logged_in
        else:
            return False
    def authenticate(self, configurationAttributes, requestParameters, step):
        authenticationService = CdiUtil.bean(AuthenticationService)

        if step == 1:
            print "Basic (lock account). Authenticate for step 1"
            facesMessages = CdiUtil.bean(FacesMessages)
            facesMessages.setKeepMessages()
            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()
            user_name = credentials.getUsername()
            user_password = credentials.getPassword()
            cacheService = CdiUtil.bean(CacheService)
            userService = CdiUtil.bean(UserService)


            logged_in = False
            if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)):
                try:
                    logged_in = authenticationService.authenticate(user_name, user_password)
                except AuthenticationException:
                    print "Basic (lock account). Authenticate. Failed to authenticate user '%s'" % user_name

            if logged_in:
                self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0))
            else:
                countInvalidLoginArributeValue = self.getUserAttributeValue(user_name, self.invalidLoginCountAttribute)
                userSatus = self.getUserAttributeValue(user_name, "gluuStatus")
                print "Current user '%s' status is '%s'" % ( user_name, userSatus )

                countInvalidLogin = StringHelper.toInteger(countInvalidLoginArributeValue, 0)

                if countInvalidLogin < self.maximumInvalidLoginAttemps:
                    countInvalidLogin = countInvalidLogin + 1
                    remainingAttempts = self.maximumInvalidLoginAttemps - countInvalidLogin

                    print "Remaining login count attempts '%s' for user '%s'" % ( remainingAttempts, user_name )

                    self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(countInvalidLogin))
                    if remainingAttempts > 0 and userSatus == "active":
                        facesMessages.add(FacesMessage.SEVERITY_INFO, StringHelper.toString(remainingAttempts)+" more attempt(s) before account is LOCKED!")

                if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and ((userSatus == None) or (userSatus == "active")):
                    print "Basic (lock account). Locking '%s' for '%s' seconds" % ( user_name, self.lockExpirationTime)
                    self.lockUser(user_name)
                    return False

                if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and userSatus == "inactive":
                    print "Basic (lock account). User '%s' is locked. Checking if we can unlock him" % user_name
                    
                    unlock_and_authenticate = False

                    object_from_store = cacheService.get(None, "lock_user_" + user_name)
                    if object_from_store == None:
                        # Object in cache was expired. We need to unlock user
                        print "Basic (lock account). User locking details for user '%s' not exists" % user_name
                        unlock_and_authenticate = True
                    else:
                        # Analyze object from cache
                        user_lock_details = json.loads(object_from_store)

                        user_lock_details_locked = user_lock_details['locked']
                        user_lock_details_created = user_lock_details['created']
                        user_lock_details_created_date = LocalDateTime.parse(user_lock_details_created, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                        user_lock_details_created_diff = Duration.between(user_lock_details_created_date, LocalDateTime.now()).getSeconds()
                        print "Basic (lock account). Get user '%s' locking details. locked: '%s', Created: '%s', Difference in seconds: '%s'" % ( user_name, user_lock_details_locked, user_lock_details_created, user_lock_details_created_diff )

                        if user_lock_details_locked and user_lock_details_created_diff >= self.lockExpirationTime:
                            print "Basic (lock account). Unlocking user '%s' after lock expiration" % user_name
                            unlock_and_authenticate = True

                    if unlock_and_authenticate:
                        self.unLockUser(user_name)
                        self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(0))
                        logged_in = authenticationService.authenticate(user_name, user_password)
                        if not logged_in:
                            # Update number of attempts 
                            self.setUserAttributeValue(user_name, self.invalidLoginCountAttribute, StringHelper.toString(1))
                            if self.maximumInvalidLoginAttemps == 1:
                                # Lock user if maximum count login attempts is 1 
                                self.lockUser(user_name)
                                return False


            return logged_in
        else:
            return False
Example #10
0
    def processOtpAuthentication(self, requestParameters, user_name, identity,
                                 otp_auth_method):
        facesMessages = CdiUtil.bean(FacesMessages)
        facesMessages.setKeepMessages()

        userService = CdiUtil.bean(UserService)

        otpCode = ServerUtil.getFirstValue(requestParameters,
                                           "loginForm:otpCode")
        if StringHelper.isEmpty(otpCode):
            facesMessages.add(FacesMessage.SEVERITY_ERROR,
                              "Failed to authenticate. OTP code is empty")
            print "OTP. Process OTP authentication. otpCode is empty"

            return False

        if otp_auth_method == "enroll":
            # Get key from session
            otp_secret_key_encoded = identity.getWorkingParameter(
                "otp_secret_key")
            if otp_secret_key_encoded == None:
                print "OTP. Process OTP authentication. OTP secret key is invalid"
                return False

            otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)

            if self.otpType == "hotp":
                validation_result = self.validateHotpKey(
                    otp_secret_key, 1, otpCode)

                if (validation_result != None) and validation_result["result"]:
                    print "OTP. Process HOTP authentication during enrollment. otpCode is valid"
                    # Store HOTP Secret Key and moving factor in user entry
                    otp_user_external_uid = "hotp:%s;%s" % (
                        otp_secret_key_encoded,
                        validation_result["movingFactor"])

                    # Add otp_user_external_uid to user's external GUID list
                    find_user_by_external_uid = userService.addUserAttribute(
                        user_name, "oxExternalUid", otp_user_external_uid)
                    if find_user_by_external_uid != None:
                        return True

                    print "OTP. Process HOTP authentication during enrollment. Failed to update user entry"
            elif self.otpType == "totp":
                validation_result = self.validateTotpKey(
                    otp_secret_key, otpCode)
                if (validation_result != None) and validation_result["result"]:
                    print "OTP. Process TOTP authentication during enrollment. otpCode is valid"
                    # Store TOTP Secret Key and moving factor in user entry
                    otp_user_external_uid = "totp:%s" % otp_secret_key_encoded

                    # Add otp_user_external_uid to user's external GUID list
                    find_user_by_external_uid = userService.addUserAttribute(
                        user_name, "oxExternalUid", otp_user_external_uid)
                    if find_user_by_external_uid != None:
                        return True

                    print "OTP. Process TOTP authentication during enrollment. Failed to update user entry"
        elif otp_auth_method == "authenticate":
            # Modified for Casa compliance

            user_enrollments = self.findEnrollments(user_name, "hotp")

            #if len(user_enrollments) == 0:
            #    print "OTP. Process OTP authentication. There is no OTP enrollment for user '%s'" % user_name
            #    facesMessages.add(FacesMessage.SEVERITY_ERROR, "There is no valid OTP user enrollments")
            #    return False

            if len(user_enrollments) > 0:
                for user_enrollment in user_enrollments:
                    user_enrollment_data = user_enrollment.split(";")
                    otp_secret_key_encoded = user_enrollment_data[0]

                    # Get current moving factor from user entry
                    moving_factor = StringHelper.toInteger(
                        user_enrollment_data[1])
                    otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)

                    # Validate TOTP
                    validation_result = self.validateHotpKey(
                        otp_secret_key, moving_factor, otpCode)
                    if (validation_result !=
                            None) and validation_result["result"]:
                        print "OTP. Process HOTP authentication during authentication. otpCode is valid"
                        otp_user_external_uid = "hotp:%s;%s" % (
                            otp_secret_key_encoded, moving_factor)
                        new_otp_user_external_uid = "hotp:%s;%s" % (
                            otp_secret_key_encoded,
                            validation_result["movingFactor"])

                        # Update moving factor in user entry
                        find_user_by_external_uid = userService.replaceUserAttribute(
                            user_name, "oxExternalUid", otp_user_external_uid,
                            new_otp_user_external_uid)
                        if find_user_by_external_uid != None:
                            return True

                        print "OTP. Process HOTP authentication during authentication. Failed to update user entry"

            user_enrollments = self.findEnrollments(user_name, "totp")

            if len(user_enrollments) > 0:
                for user_enrollment in user_enrollments:
                    otp_secret_key = self.fromBase64Url(user_enrollment)

                    # Validate TOTP
                    validation_result = self.validateTotpKey(
                        otp_secret_key, otpCode)
                    if (validation_result !=
                            None) and validation_result["result"]:
                        print "OTP. Process TOTP authentication during authentication. otpCode is valid"
                        return True

        facesMessages.add(FacesMessage.SEVERITY_ERROR,
                          "Failed to authenticate. OTP code is invalid")
        print "OTP. Process OTP authentication. OTP code is invalid"

        return False
Example #11
0
    def init(self, configurationAttributes):
        print "OTP (with lockout). Initialization"

        #############################################
        ### OTP
        if not configurationAttributes.containsKey("otp_type"):
            print "OTP (with lockout). Initialization. Property otp_type is mandatory"
            return False
        self.otpType = configurationAttributes.get("otp_type").getValue2()

        if not self.otpType in ["hotp", "totp"]:
            print "OTP (with lockout). Initialization. Property value otp_type is invalid"
            return False

        if not configurationAttributes.containsKey("issuer"):
            print "OTP (with lockout). Initialization. Property issuer is mandatory"
            return False
        self.otpIssuer = configurationAttributes.get("issuer").getValue2()

        self.customLabel = None
        if configurationAttributes.containsKey("label"):
            self.customLabel = configurationAttributes.get("label").getValue2()

        self.customQrOptions = {}
        if configurationAttributes.containsKey("qr_options"):
            self.customQrOptions = configurationAttributes.get(
                "qr_options").getValue2()

        self.use_otp_group = False
        if configurationAttributes.containsKey("otp_group"):
            self.otp_group = configurationAttributes.get(
                "otp_group").getValue2()
            self.use_otp_group = True
            print "OTP (with lockout). Initialization. Using otp only if user belong to group: %s" % self.otp_group

        self.no_lockout_admin = "admin"
        if configurationAttributes.containsKey("no_lockout_admin"):
            self.no_lockout_admin = configurationAttributes.get(
                "no_lockout_admin").getValue2()

        if self.use_otp_group:
            if not configurationAttributes.containsKey("audit_attribute"):
                print "OTP (with lockout). Initialization. Property audit_attribute is not specified"
                return False
            else:
                self.audit_attribute = configurationAttributes.get(
                    "audit_attribute").getValue2()

        self.registrationUri = None
        if configurationAttributes.containsKey("registration_uri"):
            self.registrationUri = configurationAttributes.get(
                "registration_uri").getValue2()

        validOtpConfiguration = self.loadOtpConfiguration(
            configurationAttributes)
        if not validOtpConfiguration:
            return False

        print "OTP (with lockout). Initialized successfully"
        ### OTP
        #############################################

        #############################################
        ### LOCKOUT
        self.invalidLoginCountAttribute = "oxCountInvalidLogin"
        if configurationAttributes.containsKey(
                "invalid_login_count_attribute"):
            self.invalidLoginCountAttribute = configurationAttributes.get(
                "invalid_login_count_attribute").getValue2()
        else:
            print "OTP (with lockout). Initialization. Using default attribute"

        self.maximumInvalidLoginAttemps = 3
        if configurationAttributes.containsKey(
                "maximum_invalid_login_attemps"):
            self.maximumInvalidLoginAttemps = StringHelper.toInteger(
                configurationAttributes.get(
                    "maximum_invalid_login_attemps").getValue2())
        else:
            print "OTP (with lockout). Initialization. Using default number attempts"

        self.lockExpirationTime = 180
        if configurationAttributes.containsKey("lock_expiration_time"):
            self.lockExpirationTime = StringHelper.toInteger(
                configurationAttributes.get(
                    "lock_expiration_time").getValue2())
        else:
            print "OTP (with lockout). Initialization. Using default lock expiration time"

        print "OTP (with lockout). Initialized successfully. invalid_login_count_attribute: '%s', maximum_invalid_login_attemps: '%s', lock_expiration_time: '%s'" % (
            self.invalidLoginCountAttribute, self.maximumInvalidLoginAttemps,
            self.lockExpirationTime)
        ### LOCKOUT
        #############################################

        return True
Example #12
0
    def authenticate(self, configurationAttributes, requestParameters, step):
        authenticationService = CdiUtil.bean(AuthenticationService)

        identity = CdiUtil.bean(Identity)
        credentials = identity.getCredentials()

        self.setRequestScopedParameters(identity)

        if step == 1:

            #############################################
            ### LOCKOUT
            print "OTP (with lockout). Authenticate for step 1"
            facesMessages = CdiUtil.bean(FacesMessages)
            facesMessages.setKeepMessages()
            identity = CdiUtil.bean(Identity)
            credentials = identity.getCredentials()
            user_name = credentials.getUsername()
            cacheService = CdiUtil.bean(CacheService)

            print "OTP (with lockout). Authenticate for step 1"
            authenticated_user = self.processBasicAuthentication(credentials)

            if authenticated_user != None:
                self.setUserAttributeValue(user_name,
                                           self.invalidLoginCountAttribute,
                                           StringHelper.toString(0))
            elif user_name != self.no_lockout_admin:
                countInvalidLoginArributeValue = self.getUserAttributeValue(
                    user_name, self.invalidLoginCountAttribute)
                userSatus = self.getUserAttributeValue(user_name, "gluuStatus")
                print "Current user '%s' status is '%s'" % (user_name,
                                                            userSatus)

                countInvalidLogin = StringHelper.toInteger(
                    countInvalidLoginArributeValue, 0)

                if countInvalidLogin < self.maximumInvalidLoginAttemps:
                    countInvalidLogin = countInvalidLogin + 1
                    remainingAttempts = self.maximumInvalidLoginAttemps - countInvalidLogin

                    print "Remaining login count attempts '%s' for user '%s'" % (
                        remainingAttempts, user_name)

                    self.setUserAttributeValue(
                        user_name, self.invalidLoginCountAttribute,
                        StringHelper.toString(countInvalidLogin))
                    if remainingAttempts > 0 and userSatus == "active":
                        facesMessages.add(
                            FacesMessage.SEVERITY_INFO,
                            StringHelper.toString(remainingAttempts) +
                            " more attempt(s) before account is LOCKED!")

                if (countInvalidLogin >= self.maximumInvalidLoginAttemps) and (
                    (userSatus == None) or (userSatus == "active")):
                    print "OTP (with lockout). Locking '%s' for '%s' seconds" % (
                        user_name, self.lockExpirationTime)
                    self.lockUser(user_name, self.maximumInvalidLoginAttemps)
                    return False

                if (countInvalidLogin >= self.maximumInvalidLoginAttemps
                    ) and userSatus == "inactive":
                    print "OTP (with lockout). User '%s' is locked. Checking if we can unlock him" % user_name

                    unlock_and_authenticate = False

                    object_from_store = cacheService.get(
                        None, "lock_user_" + user_name)
                    if object_from_store == None:
                        # Object in cache was expired. We need to unlock user
                        print "OTP (with lockout). User locking details for user '%s' not exists" % user_name
                        unlock_and_authenticate = True
                    else:
                        # Analyze object from cache
                        user_lock_details = json.loads(object_from_store)

                        user_lock_details_locked = user_lock_details['locked']
                        user_lock_details_created = user_lock_details[
                            'created']
                        user_lock_details_created_date = LocalDateTime.parse(
                            user_lock_details_created,
                            DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                        user_lock_details_created_diff = Duration.between(
                            user_lock_details_created_date,
                            LocalDateTime.now()).getSeconds()
                        print "OTP (with lockout). Get user '%s' locking details. locked: '%s', Created: '%s', Difference in seconds: '%s'" % (
                            user_name, user_lock_details_locked,
                            user_lock_details_created,
                            user_lock_details_created_diff)

                        if user_lock_details_locked and user_lock_details_created_diff >= self.lockExpirationTime:
                            print "OTP (with lockout). Unlocking user '%s' after lock expiration" % user_name
                            unlock_and_authenticate = True

                    if unlock_and_authenticate:
                        self.unLockUser(user_name)
                        self.setUserAttributeValue(
                            user_name, self.invalidLoginCountAttribute,
                            StringHelper.toString(0))
                        ### TODO: Fix free attempt after unlock
                        authenticated_user = self.processBasicAuthentication(
                            credentials)
                        if authenticated_user == None:
                            self.setUserAttributeValue(
                                user_name, self.invalidLoginCountAttribute,
                                StringHelper.toString(1))

            if authenticated_user == None:
                return False
            ### LOCKOUT
            #############################################

            # Check the otp_group user membership
            if (self.use_otp_group):
                print "OTP (with lockout). Authenticate for step 1. Checking if user '%s' belongs to otp_group" % authenticated_user.getUserId(
                )
                is_member_otp_group = self.isUserMemberOfGroup(
                    authenticated_user, self.audit_attribute, self.otp_group)
                if not is_member_otp_group:
                    print "OTP (with lockout). Authenticate for step 1. User '%s' not a member of otp group, skipping OTP" % authenticated_user.getUserId(
                    )
                    identity.setWorkingParameter("otp_count_login_steps", 1)
                    return True
                else:
                    print "OTP (with lockout). Authenticate for step 1. User '%s' is a member of otp group, continue to OTP" % authenticated_user.getUserId(
                    )

            otp_auth_method = "authenticate"
            # Uncomment this block if you need to allow user second OTP registration
            #enrollment_mode = ServerUtil.getFirstValue(requestParameters, "loginForm:registerButton")
            #if StringHelper.isNotEmpty(enrollment_mode):
            #    otp_auth_method = "enroll"

            if otp_auth_method == "authenticate":
                user_enrollments = self.findEnrollments(
                    authenticated_user.getUserId())
                if len(user_enrollments) == 0:
                    otp_auth_method = "enroll"
                    print "OTP (with lockout). Authenticate for step 1. There is no OTP enrollment for user '%s'. Changing otp_auth_method to '%s'" % (
                        authenticated_user.getUserId(), otp_auth_method)

            if otp_auth_method == "enroll":
                print "OTP (with lockout). Authenticate for step 1. Setting count steps: '%s'" % 3
                identity.setWorkingParameter("otp_count_login_steps", 3)

            print "OTP (with lockout). Authenticate for step 1. otp_auth_method: '%s'" % otp_auth_method
            identity.setWorkingParameter("otp_auth_method", otp_auth_method)

            return True
        elif step == 2:
            print "OTP (with lockout). Authenticate for step 2"

            authenticationService = CdiUtil.bean(AuthenticationService)
            user = authenticationService.getAuthenticatedUser()
            if user == None:
                print "OTP (with lockout). Authenticate for step 2. Failed to determine user name"
                return False

            session_id_validation = self.validateSessionId(identity)
            if not session_id_validation:
                return False

            # Restore state from session
            otp_auth_method = identity.getWorkingParameter("otp_auth_method")
            if otp_auth_method == 'enroll':
                auth_result = ServerUtil.getFirstValue(requestParameters,
                                                       "auth_result")
                if not StringHelper.isEmpty(auth_result):
                    print "OTP (with lockout). Authenticate for step 2. User not enrolled OTP"
                    return False

                print "OTP (with lockout). Authenticate for step 2. Skipping this step during enrollment"
                return True

            otp_auth_result = self.processOtpAuthentication(
                requestParameters, user.getUserId(), identity, otp_auth_method)
            print "OTP (with lockout). Authenticate for step 2. OTP authentication result: '%s'" % otp_auth_result

            return otp_auth_result
        elif step == 3:
            print "OTP (with lockout). Authenticate for step 3"

            authenticationService = CdiUtil.bean(AuthenticationService)
            user = authenticationService.getAuthenticatedUser()
            if user == None:
                print "OTP (with lockout). Authenticate for step 2. Failed to determine user name"
                return False

            session_id_validation = self.validateSessionId(identity)
            if not session_id_validation:
                return False

            # Restore state from session
            otp_auth_method = identity.getWorkingParameter("otp_auth_method")
            if otp_auth_method != 'enroll':
                return False

            otp_auth_result = self.processOtpAuthentication(
                requestParameters, user.getUserId(), identity, otp_auth_method)
            print "OTP (with lockout). Authenticate for step 3. OTP authentication result: '%s'" % otp_auth_result

            return otp_auth_result
        else:
            return False
Example #13
0
    def update(self, dynamicScopeContext, configurationAttributes):
        print "Dynamic scope [claims_scope]. Update method"

        # Get the client and session and dynamic claims
        authorizationGrant = dynamicScopeContext.getAuthorizationGrant()
        oidcClient = authorizationGrant.getClient()
        currentEntityId = "oidc:%s" % oidcClient.getClientName()
        
        # sessionDn = authorizationGrant.getSessionDn()
        # print "Dynamic scope [claims_scope]. Got session DN = '%s'" % sessionDn
        # sessionId = dynamicScopeContext.getEntryAttributeValue(sessionDn, "sessionId")
        # if ( sessionDn != None ):

        # prepare the search results attributes
        claimNamesJsonString = None
        claimsSrcJsonString = None
        
        # then we look for the SAML persistentId value in user profile
        user = dynamicScopeContext.getUser()
        userTransientIds = user.getAttributeValues("transientId")
        if ( userTransientIds != None ):
            if ( userTransientIds.size > 0 ):
                # save latest time (set to 0 initially)
                latestExpiryTimeSec = 0
                # go through existing user persistentIds
                for userTransientId in userTransientIds:
                    # if the current RP already has a mapping then skip the second phase
                    transientIdRp = StringHelper.split(userTransientId,'|')[0]
                    if ( transientIdRp == currentEntityId ):
                        print "Dynamic scope [claims_scope]. Found matching transientId '%s'" % userTransientId
                        # Format is : currentOidcRp, expiryTimeSec, userInfoUrl, accessToken
                        expiryTimeSec = StringHelper.split(userTransientId,'|')[1]
                        userInfoUrl   = StringHelper.split(userTransientId,'|')[2]
                        accessToken   = StringHelper.split(userTransientId,'|')[3]
                        # Check the last timestamp is newer than the current one and not older than 15 minutes (900 second)
                        expiryTimeSec = StringHelper.toInteger(expiryTimeSec)
                        currenttimeSec = int(round(time.time()))
                        if ( expiryTimeSec > latestExpiryTimeSec and expiryTimeSec > (currenttimeSec - 900) ):
                            # Save expiry and update/set the _claim_sources parameters
                            latestExpiryTimeSec = expiryTimeSec
                            # create a JSON object with _claim_sources for distributed claims
                            claimsSrcJsonString = '{"src1":{"endpoint":"%s","access_token":"%s"}}' % ( userInfoUrl, accessToken )
                            
                            # Set the _claim_names value to the result - static as per PCTF
                            #######################################################
                            #   "_claim_names": {
                            #     "given_name": "src1",
                            #     "family_name": "src1",
                            #     "birthdate": "src1",
                            #     "address": "src1"
                            #   },
                            # create a JSON object with _claim_sources for distributed claims
                            claimNamesJsonString = '{"given_name":"src1","family_name":"src1","birthdate":"src1","address":"src1"}'

        # set the claims if they have been found
        if ( claimNamesJsonString != None and claimsSrcJsonString != None ):
            # Get the claims object
            jsonWebResponse = dynamicScopeContext.getJsonWebResponse()
            claims = jsonWebResponse.getClaims()
            # create JSON objects
            claimNamesJson = JSONObject(claimNamesJsonString)
            claimsSrcJson = JSONObject(claimsSrcJsonString)
            # set the claims
            claims.setClaim("_claim_names", claimNamesJson)
            claims.setClaim("_claim_sources", claimsSrcJson)

        return True
    def processOtpAuthentication(self, requestParameters, user_name, identity, otp_auth_method):
        facesMessages = CdiUtil.bean(FacesMessages)
        facesMessages.setKeepMessages()

        userService = CdiUtil.bean(UserService)

        otpCode = ServerUtil.getFirstValue(requestParameters, "loginForm:otpCode")
        if StringHelper.isEmpty(otpCode):
            facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to authenticate. OTP code is empty")
            print "OTP. Process OTP authentication. otpCode is empty"

            return False
        
        if otp_auth_method == "enroll":
            # Get key from session
            otp_secret_key_encoded = identity.getWorkingParameter("otp_secret_key")
            if otp_secret_key_encoded == None:
                print "OTP. Process OTP authentication. OTP secret key is invalid"
                return False
            
            otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)

            if self.otpType == "hotp":
                validation_result = self.validateHotpKey(otp_secret_key, 1, otpCode)
                
                if (validation_result != None) and validation_result["result"]:
                    print "OTP. Process HOTP authentication during enrollment. otpCode is valid"
                    # Store HOTP Secret Key and moving factor in user entry
                    otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, validation_result["movingFactor"] )

                    # Add otp_user_external_uid to user's external GUID list
                    find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", otp_user_external_uid)
                    if find_user_by_external_uid != None:
                        return True

                    print "OTP. Process HOTP authentication during enrollment. Failed to update user entry"
            elif self.otpType == "totp":
                validation_result = self.validateTotpKey(otp_secret_key, otpCode)
                if (validation_result != None) and validation_result["result"]:
                    print "OTP. Process TOTP authentication during enrollment. otpCode is valid"
                    # Store TOTP Secret Key and moving factor in user entry
                    otp_user_external_uid = "totp:%s" % otp_secret_key_encoded

                    # Add otp_user_external_uid to user's external GUID list
                    find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", otp_user_external_uid)
                    if find_user_by_external_uid != None:
                        return True

                    print "OTP. Process TOTP authentication during enrollment. Failed to update user entry"
        elif otp_auth_method == "authenticate":
            user_enrollments = self.findEnrollments(user_name)

            if len(user_enrollments) == 0:
                print "OTP. Process OTP authentication. There is no OTP enrollment for user '%s'" % user_name
                facesMessages.add(FacesMessage.SEVERITY_ERROR, "There is no valid OTP user enrollments")
                return False

            if self.otpType == "hotp":
                for user_enrollment in user_enrollments:
                    user_enrollment_data = user_enrollment.split(";")
                    otp_secret_key_encoded = user_enrollment_data[0]

                    # Get current moving factor from user entry
                    moving_factor = StringHelper.toInteger(user_enrollment_data[1])
                    otp_secret_key = self.fromBase64Url(otp_secret_key_encoded)

                    # Validate TOTP
                    validation_result = self.validateHotpKey(otp_secret_key, moving_factor, otpCode)
                    if (validation_result != None) and validation_result["result"]:
                        print "OTP. Process HOTP authentication during authentication. otpCode is valid"
                        otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, moving_factor )
                        new_otp_user_external_uid = "hotp:%s;%s" % ( otp_secret_key_encoded, validation_result["movingFactor"] )
    
                        # Update moving factor in user entry
                        find_user_by_external_uid = userService.replaceUserAttribute(user_name, "oxExternalUid", otp_user_external_uid, new_otp_user_external_uid)
                        if find_user_by_external_uid != None:
                            return True
    
                        print "OTP. Process HOTP authentication during authentication. Failed to update user entry"
            elif self.otpType == "totp":
                for user_enrollment in user_enrollments:
                    otp_secret_key = self.fromBase64Url(user_enrollment)

                    # Validate TOTP
                    validation_result = self.validateTotpKey(otp_secret_key, otpCode)
                    if (validation_result != None) and validation_result["result"]:
                        print "OTP. Process TOTP authentication during authentication. otpCode is valid"
                        return True

        facesMessages.add(FacesMessage.SEVERITY_ERROR, "Failed to authenticate. OTP code is invalid")
        print "OTP. Process OTP authentication. OTP code is invalid"

        return False