def sendDevicePushNotification(self, user, app_id, u2f_device, super_gluu_request): device_data = u2f_device.getDeviceData() if device_data == None: return {"send_android":0,"send_ios":0} platform = device_data.getPlatform() push_token = device_data.getPushToken() pushNotificationContext = PushNotificationContext(app_id,super_gluu_request) pushNotificationContext.debugEnabled = self.debugEnabled pushNotificationContext.user = user pushNotificationContext.u2fDevice = u2f_device pushNotificationContext.devicePlatform = platform pushNotificationContext.pushToken = push_token send_ios = 0 send_android = 0 if StringHelper.equalsIgnoreCase(platform,"ios") and StringHelper.isNotEmpty(push_token): # Sending notification to iOS user's device if self.pushAppleService == None: print "Super-Gluu-Push. Apple push notification service disabled" else: self.sendApplePushNotification(pushNotificationContext) send_ios = 1 if StringHelper.equalsIgnoreCase(platform,"android") and StringHelper.isNotEmpty(push_token): # Sending notification to android user's device if self.pushAndroidService == None: print "Super-Gluu-Push. Android push notification service disabled" else: self.sendAndroidPushNotification(pushNotificationContext) send_android = 1 return {"send_android":send_android,"send_ios":send_ios}
def is_session_authenticated(self, sessionId): if sessionId == None: return False state = sessionId.getState() custom_state = sessionId.getSessionAttributes().get(SessionIdService.SESSION_CUSTOM_STATE) if state == None: print "Super-Gluu-RO. Session {%s} has no state variable set" % sessionId.getId() return False state_unauthenticated = SessionIdState.UNAUTHENTICATED == state state_authenticated = SessionIdState.AUTHENTICATED == state custom_state_declined = StringHelper.equalsIgnoreCase("declined",custom_state) custom_state_expired = StringHelper.equalsIgnoreCase("expired",custom_state) custom_stated_approved = StringHelper.equalsIgnoreCase("approved",custom_state) if state_unauthenticated and (custom_state_declined or custom_state_expired): print "Super-Gluu-RO. Session {%s} isn't authenticated" % sessionId.getId() return False if state_authenticated or (state_unauthenticated and custom_stated_approved): print "Super-Gluu-RO. Session {%s} is authenticated" % sessionId.getId() return True return False
def verify_session_ownership(self, sessionId, user, client): session_attributes = sessionId.getSessionAttributes() client_id = session_attributes.get(self.clientIdSessionParamName) if not StringHelper.equalsIgnoreCase(client.getClientId(),client_id): print "Super-Gluu-RO. Session {%s} client_id mismatch" % sessionId.getId() return False user_id = session_attributes.get(Constants.AUTHENTICATED_USER) if not StringHelper.equalsIgnoreCase(user_id,user.getUserId()): print "Super-Gluu-RO. Session {%s} user_id mismatch" % sessionId.getId() return False return True
def authenticate(self, context): if self.perform_preliminary_user_authentication(context) == False: print "Super-Gluu-Radius. User authentication state not validated" return False step = context.getHttpRequest().getParameter(self.stepParamName) if StringHelper.equalsIgnoreCase(step,self.initiateAuthStepName): return self.initiate_authentication(context) elif StringHelper.equalsIgnoreCase(step,self.resendNotificationStepName): return self.resend_push_notification(context) elif StringHelper.equalsIgnoreCase(step,self.verifyAuthStepName): return self.verify_authentication(context) else: context.setUser(None) print "Super-Gluu-RO. Unknown authentication step '%s'" % step return False
def __init__(self, serviceMode, credentialsFile): self.pushSnsMode = False self.pushGluuMode = False self.pushNotificationsEnabled = False self.titleTemplate = "Super-Gluu" self.messageTemplate = "Super-Gluu login request to %s" self.debugEnabled = True self.httpConnTimeout = 15 * 1000 # in milliseconds creds = self.loadCredentials(credentialsFile) if creds == None: return None if StringHelper.equalsIgnoreCase(serviceMode,"sns"): self.initSnsPushNotifications(creds) elif StringHelper.equalsIgnoreCase(serviceMode,"gluu"): self.initGluuPushNotifications(creds) else: self.initNativePushNotifications(creds)
def isUserMemberOfGroup(self, user, attribute, group): is_member = False member_of_list = user.getAttributeValues(attribute) if (member_of_list != None): for member_of in member_of_list: if StringHelper.equalsIgnoreCase(group, member_of) or member_of.endswith(group): is_member = True break return is_member
def loadOtpConfiguration(self, configurationAttributes): print "OTP. Load OTP configuration" if not configurationAttributes.containsKey("otp_conf_file"): return False otp_conf_file = configurationAttributes.get("otp_conf_file").getValue2() # Load configuration from file f = open(otp_conf_file, 'r') try: otpConfiguration = json.loads(f.read()) except: print "OTP. Load OTP configuration. Failed to load configuration from file:", otp_conf_file return False finally: f.close() # Check configuration file settings try: self.hotpConfiguration = otpConfiguration["hotp"] self.totpConfiguration = otpConfiguration["totp"] hmacShaAlgorithm = self.totpConfiguration["hmacShaAlgorithm"] hmacShaAlgorithmType = None if StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha1"): hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_1 elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha256"): hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_256 elif StringHelper.equalsIgnoreCase(hmacShaAlgorithm, "sha512"): hmacShaAlgorithmType = HmacShaAlgorithm.HMAC_SHA_512 else: print "OTP. Load OTP configuration. Invalid TOTP HMAC SHA algorithm: '%s'" % hmacShaAlgorithm self.totpConfiguration["hmacShaAlgorithmType"] = hmacShaAlgorithmType except: print "OTP. Load OTP configuration. Invalid configuration file '%s' format. Exception: '%s'" % (otp_conf_file, sys.exc_info()[1]) return False return True
def getGeolocation(self, identity): session_attributes = identity.getSessionId().getSessionAttributes() if session_attributes.containsKey("remote_ip"): remote_ip = session_attributes.get("remote_ip") if StringHelper.isNotEmpty(remote_ip): httpService = CdiUtil.bean(HttpService) http_client = httpService.getHttpsClient() http_client_params = http_client.getParams() http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 4 * 1000) geolocation_service_url = "http://ip-api.com/json/%s?fields=country,city,status,message" % remote_ip geolocation_service_headers = { "Accept" : "application/json" } try: http_service_response = httpService.executeGet(http_client, geolocation_service_url, geolocation_service_headers) http_response = http_service_response.getHttpResponse() except: print "Casa. Determine remote location. Exception: ", sys.exc_info()[1] return None try: if not httpService.isResponseStastusCodeOk(http_response): print "Casa. Determine remote location. Get non 200 OK response from server:", str(http_response.getStatusLine().getStatusCode()) httpService.consume(http_response) return None response_bytes = httpService.getResponseContent(http_response) response_string = httpService.convertEntityToString(response_bytes, Charset.forName("UTF-8")) httpService.consume(http_response) finally: http_service_response.closeConnection() if response_string == None: print "Casa. Determine remote location. Get empty response from location server" return None response = json.loads(response_string) if not StringHelper.equalsIgnoreCase(response['status'], "success"): print "Casa. Determine remote location. Get response with status: '%s'" % response['status'] return None return response return None
def prepareForStep(self, configurationAttributes, requestParameters, step): extensionResult = self.extensionPrepareForStep(configurationAttributes, requestParameters, step) if extensionResult != None: return extensionResult print "Passport. prepareForStep called %s" % str(step) identity = CdiUtil.bean(Identity) if step == 1: #re-read the strategies config (for instance to know which strategies have enabled the email account linking) self.parseProviderConfigs() identity.setWorkingParameter("externalProviders", json.dumps(self.registeredProviders)) providerParam = self.customAuthzParameter url = None sessionAttributes = identity.getSessionId().getSessionAttributes() self.skipProfileUpdate = StringHelper.equalsIgnoreCase(sessionAttributes.get("skipPassportProfileUpdate"), "true") #this param could have been set previously in authenticate step if current step is being retried provider = identity.getWorkingParameter("selectedProvider") if provider != None: url = self.getPassportRedirectUrl(provider) identity.setWorkingParameter("selectedProvider", None) elif providerParam != None: paramValue = sessionAttributes.get(providerParam) if paramValue != None: print "Passport. prepareForStep. Found value in custom param of authorization request: %s" % paramValue provider = self.getProviderFromJson(paramValue) if provider == None: print "Passport. prepareForStep. A provider value could not be extracted from custom authorization request parameter" elif not provider in self.registeredProviders: print "Passport. prepareForStep. Provider '%s' not part of known configured IDPs/OPs" % provider else: url = self.getPassportRedirectUrl(provider) if url == None: print "Passport. prepareForStep. A page to manually select an identity provider will be shown" else: facesService = CdiUtil.bean(FacesService) facesService.redirectToExternalURL(url) return True
def init(self, configurationAttributes): print "Super-Gluu-RO Init" if not configurationAttributes.containsKey("application_id"): print "Super-Gluu-Radius RO PW Init Failed. application_id property is required" return False if not configurationAttributes.containsKey("credentials_file"): print "Super-Gluu-RO Init Failed. credentials_file is required" return False notificationServiceMode = None if configurationAttributes.containsKey("notification_service_mode"): notificationServiceMode = configurationAttributes.get("notification_service_mode").getValue2() self.applicationId = "*" # wildcard. Selects all devices irrespective of the application if configurationAttributes.containsKey("application_id"): self.applicationId = configurationAttributes.get("application_id").getValue2() credentialsFile = configurationAttributes.get("credentials_file").getValue2() if configurationAttributes.containsKey("push_notification_title"): self.pushNotificationManager.titleTemplate = configurationAttributes.get("push_notification_title").getValue2() if configurationAttributes.containsKey("push_notification_message"): self.pushNotificationManager.messageTemplate = configurationAttributes.get("push_notification_message").getValue2() self.authWithoutPassword = False if configurationAttributes.containsKey("auth_without_password"): auth_without_password = configurationAttributes.get("auth_without_password").getValue2() if StringHelper.equalsIgnoreCase(auth_without_password,"yes"): self.authWithoutPassword = True self.issuerId = CdiUtil.bean(ConfigurationFactory).getAppConfiguration().getIssuer() if configurationAttributes.containsKey("issuer_id"): self.issuerId = configurationAttributes.get("issuer_id").getValue2() self.pushNotificationManager = PushNotificationManager(notificationServiceMode,credentialsFile) self.networkApi = NetworkApi() return True
def get_geolocation_data(self, remote_ip): print "NetApi. Determining remote location for ip address '%s'" % remote_ip httpService = CdiUtil.bean(HttpService) http_client = httpService.getHttpsClient() http_client_params = http_client.getParams() http_client_params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,self.conn_timeout) geolocation_service_url = "http://ip-api.com/json/%s?fields=49177" % remote_ip geolocation_service_headers = { "Accept": "application/json"} try: http_service_response = httpService.executeGet(http_client,geolocation_service_url,geolocation_service_headers) http_response = http_service_response.getHttpResponse() except: print "NetApi. Could not determine remote location: ", sys.exc_info()[1] return None try: if not httpService.isResponseStastusCodeOk(http_response): http_error_str = str(http_response.getStatusLine().getStatusCode()) print "NetApi. Could not determine remote location: ",http_error_str httpService.consume(http_response) return None response_bytes = httpService.getResponseContent(http_response) response_string = httpService.convertEntityToString(response_bytes) httpService.consume(http_response) finally: http_service_response.closeConnection() if response_string == None: print "NetApi. Could not determine remote location. Empty respone from server" return None response = json.loads(response_string) if not StringHelper.equalsIgnoreCase(response['status'],"success"): print "NetApi. Could not determine remote location. ip-api status: '%s'" % response['status'] return None return GeolocationData(response)
def authenticate(self, configurationAttributes, requestParameters, step): identity = CdiUtil.bean(Identity) credentials = identity.getCredentials() session_attributes = identity.getSessionId().getSessionAttributes() self.setRequestScopedParameters(identity) if (step == 1): print "UAF. Authenticate for step 1" user_name = credentials.getUsername() authenticated_user = self.processBasicAuthentication(credentials) if authenticated_user == None: return False uaf_auth_method = "authenticate" # Uncomment this block if you need to allow user second device registration #enrollment_mode = ServerUtil.getFirstValue(requestParameters, "loginForm:registerButton") #if StringHelper.isNotEmpty(enrollment_mode): # uaf_auth_method = "enroll" if uaf_auth_method == "authenticate": user_enrollments = self.findEnrollments(credentials) if len(user_enrollments) == 0: uaf_auth_method = "enroll" print "UAF. Authenticate for step 1. There is no UAF enrollment for user '%s'. Changing uaf_auth_method to '%s'" % (user_name, uaf_auth_method) print "UAF. Authenticate for step 1. uaf_auth_method: '%s'" % uaf_auth_method identity.setWorkingParameter("uaf_auth_method", uaf_auth_method) return True elif (step == 2): print "UAF. Authenticate for step 2" session_id = CdiUtil.bean(SessionIdService).getSessionIdFromCookie() if StringHelper.isEmpty(session_id): print "UAF. Prepare for step 2. Failed to determine session_id" return False user = authenticationService.getAuthenticatedUser() if (user == None): print "UAF. Authenticate for step 2. Failed to determine user name" return False user_name = user.getUserId() uaf_auth_result = ServerUtil.getFirstValue(requestParameters, "auth_result") if uaf_auth_result != "success": print "UAF. Authenticate for step 2. auth_result is '%s'" % uaf_auth_result return False # Restore state from session uaf_auth_method = session_attributes.get("uaf_auth_method") if not uaf_auth_method in ['enroll', 'authenticate']: print "UAF. Authenticate for step 2. Failed to authenticate user. uaf_auth_method: '%s'" % uaf_auth_method return False # Request STATUS_OBB if True: #TODO: Remove this condition # It's workaround becuase it's not possible to call STATUS_OBB 2 times. First time on browser and second ime on server uaf_user_device_handle = ServerUtil.getFirstValue(requestParameters, "auth_handle") else: uaf_obb_auth_method = session_attributes.get("uaf_obb_auth_method") uaf_obb_server_uri = session_attributes.get("uaf_obb_server_uri") uaf_obb_start_response = session_attributes.get("uaf_obb_start_response") # Prepare STATUS_OBB uaf_obb_start_response_json = json.loads(uaf_obb_start_response) uaf_obb_status_request_dictionary = { "operation": "STATUS_%s" % uaf_obb_auth_method, "userName": user_name, "needDetails": 1, "oobStatusHandle": uaf_obb_start_response_json["oobStatusHandle"], } uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':')) print "UAF. Authenticate for step 2. Prepared STATUS request: '%s' to send to '%s'" % (uaf_obb_status_request, uaf_obb_server_uri) uaf_status_obb_response = self.executePost(uaf_obb_server_uri, uaf_obb_status_request) if uaf_status_obb_response == None: return False print "UAF. Authenticate for step 2. Get STATUS response: '%s'" % uaf_status_obb_response uaf_status_obb_response_json = json.loads(uaf_status_obb_response) if uaf_status_obb_response_json["statusCode"] != 4000: print "UAF. Authenticate for step 2. UAF operation status is invalid. statusCode: '%s'" % uaf_status_obb_response_json["statusCode"] return False uaf_user_device_handle = uaf_status_obb_response_json["additionalInfo"]["authenticatorsResult"]["handle"] if StringHelper.isEmpty(uaf_user_device_handle): print "UAF. Prepare for step 2. Failed to get UAF handle" return False uaf_user_external_uid = "uaf:%s" % uaf_user_device_handle print "UAF. Authenticate for step 2. UAF handle: '%s'" % uaf_user_external_uid if uaf_auth_method == "authenticate": # Validate if user used device with same keYHandle user_enrollments = self.findEnrollments(credentials) if len(user_enrollments) == 0: uaf_auth_method = "enroll" print "UAF. Authenticate for step 2. There is no UAF enrollment for user '%s'." % user_name return False for user_enrollment in user_enrollments: if StringHelper.equalsIgnoreCase(user_enrollment, uaf_user_device_handle): print "UAF. Authenticate for step 2. There is UAF enrollment for user '%s'. User authenticated successfully" % user_name return True else: userService = CdiUtil.bean(UserService) # Double check just to make sure. We did checking in previous step # Check if there is user which has uaf_user_external_uid # Avoid mapping user cert to more than one IDP account find_user_by_external_uid = userService.getUserByAttribute("oxExternalUid", uaf_user_external_uid) if find_user_by_external_uid == None: # Add uaf_user_external_uid to user's external GUID list find_user_by_external_uid = userService.addUserAttribute(user_name, "oxExternalUid", uaf_user_external_uid) if find_user_by_external_uid == None: print "UAF. Authenticate for step 2. Failed to update current user" return False return True return False else: return False
def authenticate(self, configurationAttributes, requestParameters, step): identity = CdiUtil.bean(Identity) userService = CdiUtil.bean(UserService) authenticationService = CdiUtil.bean(AuthenticationService) mapUserDeployment = False enrollUserDeployment = False if (configurationAttributes.containsKey("gplus_deployment_type")): deploymentType = StringHelper.toLowerCase(configurationAttributes.get("gplus_deployment_type").getValue2()) if (StringHelper.equalsIgnoreCase(deploymentType, "map")): mapUserDeployment = True if (StringHelper.equalsIgnoreCase(deploymentType, "enroll")): enrollUserDeployment = True if (step == 1): print "Google+ Authenticate for step 1" gplusAuthCodeArray = requestParameters.get("gplus_auth_code") gplusAuthCode = gplusAuthCodeArray[0] # Check if user uses basic method to log in useBasicAuth = False if (StringHelper.isEmptyString(gplusAuthCode)): useBasicAuth = True # Use basic method to log in if (useBasicAuth): print "Google+ Authenticate for step 1. Basic authentication" identity.setWorkingParameter("gplus_count_login_steps", 1) credentials = identity.getCredentials() userName = credentials.getUsername() userPassword = credentials.getPassword() loggedIn = False if (StringHelper.isNotEmptyString(userName) and StringHelper.isNotEmptyString(userPassword)): userService = CdiUtil.bean(UserService) loggedIn = authenticationService.authenticate(userName, userPassword) if (not loggedIn): return False return True # Use Google+ method to log in print "Google+ Authenticate for step 1. gplusAuthCode:", gplusAuthCode currentClientSecrets = self.getCurrentClientSecrets(self.clientSecrets, configurationAttributes, requestParameters) if (currentClientSecrets == None): print "Google+ Authenticate for step 1. Client secrets configuration is invalid" return False print "Google+ Authenticate for step 1. Attempting to gets tokens" tokenResponse = self.getTokensByCode(self.clientSecrets, configurationAttributes, gplusAuthCode) if ((tokenResponse == None) or (tokenResponse.getIdToken() == None) or (tokenResponse.getAccessToken() == None)): print "Google+ Authenticate for step 1. Failed to get tokens" return False else: print "Google+ Authenticate for step 1. Successfully gets tokens" jwt = Jwt.parse(tokenResponse.getIdToken()) # TODO: Validate ID Token Signature gplusUserUid = jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER) print "Google+ Authenticate for step 1. Found Google user ID in the ID token: '%s'" % gplusUserUid if (mapUserDeployment): # Use mapping to local IDP user print "Google+ Authenticate for step 1. Attempting to find user by oxExternalUid: 'gplus:%s'" % gplusUserUid # Check if there is user with specified gplusUserUid foundUser = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplusUserUid) if (foundUser == None): print "Google+ Authenticate for step 1. Failed to find user" print "Google+ Authenticate for step 1. Setting count steps to 2" identity.setWorkingParameter("gplus_count_login_steps", 2) identity.setWorkingParameter("gplus_user_uid", gplusUserUid) return True foundUserName = foundUser.getUserId() print "Google+ Authenticate for step 1. foundUserName: '******'" % foundUserName userAuthenticated = authenticationService.authenticate(foundUserName) if (userAuthenticated == False): print "Google+ Authenticate for step 1. Failed to authenticate user" return False print "Google+ Authenticate for step 1. Setting count steps to 1" identity.setWorkingParameter("gplus_count_login_steps", 1) postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser) print "Google+ Authenticate for step 1. postLoginResult: '%s'" % postLoginResult return postLoginResult elif (enrollUserDeployment): # Use auto enrollment to local IDP print "Google+ Authenticate for step 1. Attempting to find user by oxExternalUid: 'gplus:%s'" % gplusUserUid # Check if there is user with specified gplusUserUid foundUser = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplusUserUid) if (foundUser == None): # Auto user enrollemnt print "Google+ Authenticate for step 1. There is no user in LDAP. Adding user to local LDAP" print "Google+ Authenticate for step 1. Attempting to gets user info" userInfoResponse = self.getUserInfo(currentClientSecrets, configurationAttributes, tokenResponse.getAccessToken()) if ((userInfoResponse == None) or (userInfoResponse.getClaims().size() == 0)): print "Google+ Authenticate for step 1. Failed to get user info" return False else: print "Google+ Authenticate for step 1. Successfully gets user info" gplusResponseAttributes = userInfoResponse.getClaims() # Convert Google+ user claims to lover case gplusResponseNormalizedAttributes = HashMap() for gplusResponseAttributeEntry in gplusResponseAttributes.entrySet(): gplusResponseNormalizedAttributes.put( StringHelper.toLowerCase(gplusResponseAttributeEntry.getKey()), gplusResponseAttributeEntry.getValue()) currentAttributesMapping = self.getCurrentAttributesMapping(self.attributesMapping, configurationAttributes, requestParameters) print "Google+ Authenticate for step 1. Using next attributes mapping '%s'" % currentAttributesMapping newUser = User() for attributesMappingEntry in currentAttributesMapping.entrySet(): remoteAttribute = attributesMappingEntry.getKey() localAttribute = attributesMappingEntry.getValue() localAttributeValue = gplusResponseNormalizedAttributes.get(remoteAttribute) if (localAttribute != None): newUser.setAttribute(localAttribute, localAttributeValue) if (newUser.getAttribute("sn") == None): newUser.setAttribute("sn", gplusUserUid) if (newUser.getAttribute("cn") == None): newUser.setAttribute("cn", gplusUserUid) # Add mail to oxTrustEmail so that the user's # email is available through the SCIM interface # too. if (newUser.getAttribute("oxTrustEmail") is None and newUser.getAttribute("mail") is not None): oxTrustEmail = { "value": newUser.getAttribute("mail"), "display": newUser.getAttribute("mail"), "primary": True, "operation": None, "reference": None, "type": "other" } newUser.setAttribute("oxTrustEmail", json.dumps(oxTrustEmail)) newUser.setAttribute("oxExternalUid", "gplus:" + gplusUserUid) print "Google+ Authenticate for step 1. Attempting to add user '%s' with next attributes '%s'" % (gplusUserUid, newUser.getCustomAttributes()) foundUser = userService.addUser(newUser, True) print "Google+ Authenticate for step 1. Added new user with UID: '%s'" % foundUser.getUserId() foundUserName = foundUser.getUserId() print "Google+ Authenticate for step 1. foundUserName: '******'" % foundUserName userAuthenticated = authenticationService.authenticate(foundUserName) if (userAuthenticated == False): print "Google+ Authenticate for step 1. Failed to authenticate user" return False print "Google+ Authenticate for step 1. Setting count steps to 1" identity.setWorkingParameter("gplus_count_login_steps", 1) print "Google+ Authenticate for step 1. Attempting to run extension postLogin" postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser) print "Google+ Authenticate for step 1. postLoginResult: '%s'" % postLoginResult return postLoginResult else: # Check if there is user with specified gplusUserUid print "Google+ Authenticate for step 1. Attempting to find user by uid: '%s'" % gplusUserUid foundUser = userService.getUser(gplusUserUid) if (foundUser == None): print "Google+ Authenticate for step 1. Failed to find user" return False foundUserName = foundUser.getUserId() print "Google+ Authenticate for step 1. foundUserName: '******'" % foundUserName userAuthenticated = authenticationService.authenticate(foundUserName) if (userAuthenticated == False): print "Google+ Authenticate for step 1. Failed to authenticate user" return False print "Google+ Authenticate for step 1. Setting count steps to 1" identity.setWorkingParameter("gplus_count_login_steps", 1) postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser) print "Google+ Authenticate for step 1. postLoginResult: '%s'" % postLoginResult return postLoginResult elif (step == 2): print "Google+ Authenticate for step 2" sessionAttributes = identity.getSessionId().getSessionAttributes() if (sessionAttributes == None) or not sessionAttributes.containsKey("gplus_user_uid"): print "Google+ Authenticate for step 2. gplus_user_uid is empty" return False gplusUserUid = sessionAttributes.get("gplus_user_uid") passed_step1 = StringHelper.isNotEmptyString(gplusUserUid) if (not passed_step1): return False identity = CdiUtil.bean(Identity) credentials = identity.getCredentials() userName = credentials.getUsername() userPassword = credentials.getPassword() loggedIn = False if (StringHelper.isNotEmptyString(userName) and StringHelper.isNotEmptyString(userPassword)): loggedIn = authenticationService.authenticate(userName, userPassword) if (not loggedIn): return False # Check if there is user which has gplusUserUid # Avoid mapping Google account to more than one IDP account foundUser = userService.getUserByAttribute("oxExternalUid", "gplus:" + gplusUserUid) if (foundUser == None): # Add gplusUserUid to user one id UIDs foundUser = userService.addUserAttribute(userName, "oxExternalUid", "gplus:" + gplusUserUid) if (foundUser == None): print "Google+ Authenticate for step 2. Failed to update current user" return False postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser) print "Google+ Authenticate for step 2. postLoginResult: '%s'" % postLoginResult return postLoginResult else: foundUserName = foundUser.getUserId() print "Google+ Authenticate for step 2. foundUserName: '******'" % foundUserName if StringHelper.equals(userName, foundUserName): postLoginResult = self.extensionPostLogin(configurationAttributes, foundUser) print "Google+ Authenticate for step 2. postLoginResult: '%s'" % postLoginResult return postLoginResult return False else: return False
def prepareForStep(self, configurationAttributes, requestParameters, step): authenticationService = CdiUtil.bean(AuthenticationService) identity = CdiUtil.bean(Identity) credentials = identity.getCredentials() session_attributes = identity.getSessionId().getSessionAttributes() self.setRequestScopedParameters(identity) if (step == 1): return True elif (step == 2): print "UAF. Prepare for step 2" session_id = CdiUtil.bean(SessionIdService).getSessionIdFromCookie() if StringHelper.isEmpty(session_id): print "UAF. Prepare for step 2. Failed to determine session_id" return False user = authenticationService.getAuthenticatedUser() if (user == None): print "UAF. Prepare for step 2. Failed to determine user name" return False uaf_auth_method = session_attributes.get("uaf_auth_method") if StringHelper.isEmpty(uaf_auth_method): print "UAF. Prepare for step 2. Failed to determine auth_method" return False print "UAF. Prepare for step 2. uaf_auth_method: '%s'" % uaf_auth_method uaf_obb_auth_method = "OOB_REG" uaf_obb_server_uri = self.uaf_server_uri + "/nnl/v2/reg" if StringHelper.equalsIgnoreCase(uaf_auth_method, "authenticate"): uaf_obb_auth_method = "OOB_AUTH" uaf_obb_server_uri = self.uaf_server_uri + "/nnl/v2/auth" # Prepare START_OBB uaf_obb_start_request_dictionary = { "operation": "START_%s" % uaf_obb_auth_method, "userName": user.getUserId(), "policyName": "default", "oobMode": { "qr": "true", "rawData": "false", "push": "false" } } uaf_obb_start_request = json.dumps(uaf_obb_start_request_dictionary, separators=(',',':')) print "UAF. Prepare for step 2. Prepared START request: '%s' to send to '%s'" % (uaf_obb_start_request, uaf_obb_server_uri) # Request START_OBB uaf_obb_start_response = self.executePost(uaf_obb_server_uri, uaf_obb_start_request) if uaf_obb_start_response == None: return False print "UAF. Prepare for step 2. Get START response: '%s'" % uaf_obb_start_response uaf_obb_start_response_json = json.loads(uaf_obb_start_response) # Prepare STATUS_OBB #TODO: Remove needDetails parameter uaf_obb_status_request_dictionary = { "operation": "STATUS_%s" % uaf_obb_auth_method, "userName": user.getUserId(), "needDetails": 1, "oobStatusHandle": uaf_obb_start_response_json["oobStatusHandle"], } uaf_obb_status_request = json.dumps(uaf_obb_status_request_dictionary, separators=(',',':')) print "UAF. Prepare for step 2. Prepared STATUS request: '%s' to send to '%s'" % (uaf_obb_status_request, uaf_obb_server_uri) identity.setWorkingParameter("uaf_obb_auth_method", uaf_obb_auth_method) identity.setWorkingParameter("uaf_obb_server_uri", uaf_obb_server_uri) identity.setWorkingParameter("uaf_obb_start_response", uaf_obb_start_response) identity.setWorkingParameter("qr_image", uaf_obb_start_response_json["modeResult"]["qrCode"]["qrImage"]) identity.setWorkingParameter("uaf_obb_status_request", uaf_obb_status_request) return True else: return False
def prepareForFirstStep(self, configurationAttributes, requestParameters, step): if (self.getAuthenticatedUser() is not None): print "SPNEGO. User is already authenticated" return False identity = CdiUtil.bean(Identity) if(identity.getWorkingParameter('spnego_auth_success') is True): identity.setWorkingParameter('spnego_auth_success',False) identity.setWorkingParameter('spnego_error_msg',None) if self.alternativeAcr is None: identity.setWorkingParameter('spnego_valid_alternative_acr',False) identity.setWorkingParameter('spnego_alternative_acr',None) else: identity.setWorkingParameter('spnego_valid_alternative_acr',True) identity.setWorkingParameter('spnego_alternative_acr',self.alternativeAcr) httpauth = self.parseHttpAuthorization() if (httpauth is None): print "SPNEGO. No authorization headers" identity.setWorkingParameter('spnego_auth_success',False) identity.setWorkingParameter('spnego_error_msg','spnego.error.no_auth_header') authn_header = SpnegoUtil.buildAuthenticateHeaderValue(None) self.addHttpResponseHeader(SpnegoConstants.WWW_AUTHENTICATE_HEADER_NAME,authn_header) self.setResponseHttpStatus(SpnegoConstants.HTTP_UNAUTHORIZED_STATUS_CODE) return True if (not StringHelper.equalsIgnoreCase(httpauth.getScheme(),SpnegoConstants.NEGOTIATE_AUTH_SCHEME)): print "SPNEGO. Unsupported authentication scheme (%s)" % (httpauth.getScheme()) identity.setWorkingParameter('spnego_auth_success',False) identity.setWorkingParameter('spnego_error_msg','spnego.error.unsupported_auth_scheme') if self.alternativeAcr is not None: identity.setWorkingParameter('spnego_fatal_error',True) authn_header = SpnegoUtil.buildAuthenticateHeaderValue(None) self.addHttpResponseHeader(SpnegoConstants.WWW_AUTHENTICATE_HEADER_NAME,authn_header) self.setResponseHttpStatus(SpnegoConstants.HTTP_UNAUTHORIZED_STATUS_CODE) return True config_provider = self.configProvider auth_token = httpauth.getToken() spnego_authenticator = self.authenticatorFactory.createAuthenticator(auth_token,config_provider) try: spnego_principal = spnego_authenticator.authenticate() except SpnegoAuthError: identity.setWorkingParameter('spnego_fatal_error',True) identity.setWorkingParameter('spnego_auth_success',False) identity.setWorkingParameter('spnego_error_msg','spnego.error.fatal_error') authn_header = SpnegoUtil.buildAuthenticateHeaderValue(None) self.addHttpResponseHeader(SpnegoConstants.WWW_AUTHENTICATE_HEADER_NAME,authn_header) self.setResponseHttpStatus(SpnegoConstants.HTTP_UNAUTHORIZED_STATUS_CODE) return True if (spnego_principal is None): print "SPNEGO. Authentication handshake incomplete" identity.setWorkingParameter('spnego_auth_success',False) identity.setWorkingParameter('spnego_error_msg','spnego.error.handshake_incomplete') authn_header = self.buildAuthenticationHeader(spnego_authenticator) self.addHttpResponseHeader(SpnegoConstants.WWW_AUTHENTICATE_HEADER_NAME,authn_header) self.setResponseHttpStatus(SpnegoConstants.HTTP_UNAUTHORIZED_STATUS_CODE) return True user = self.findUser(spnego_principal.getUsername()) if (user is None): print "SPNEGO. User '%s' not found in the database" % (spnego_principal.getUsername()) identity.setWorkingParameter('spnego_auth_success',False) identity.setWorkingParameter('spnego_error_msg','spnego.error.user_not_found') else: print "SPNEO. Authentication successful for `%s`" % (spnego_principal.getUsername()) identity.setWorkingParameter('spnego_auth_success',True) identity.setWorkingParameter('spnego_principal',spnego_principal.getPrincipalName()) identity.setWorkingParameter('spnego_username',spnego_principal.getUsername()) if (spnego_authenticator.getResponseToken() is not None): authn_header = self.buildAuthenticationHeader(spnego_authenticator) self.addHttpResponseHeader(SpnegoConstants.WWW_AUTHENTICATE_HEADER_NAME,authn_header) return True
def authenticate(self, configurationAttributes, requestParameters, step): extensionResult = self.extensionAuthenticate(configurationAttributes, requestParameters, step) if extensionResult != None: return extensionResult print "Passport. authenticate for step %s called" % str(step) identity = CdiUtil.bean(Identity) # Loading self.registeredProviders in case passport destroyed if not hasattr(self, 'registeredProviders'): print "Passport. Fetching registered providers." self.parseProviderConfigs() if step == 1: # Get JWT token jwt_param = ServerUtil.getFirstValue(requestParameters, "user") if jwt_param != None: print "Passport. authenticate for step 1. JWT user profile token found" # Parse JWT and validate jwt = Jwt.parse(jwt_param) if not self.validSignature(jwt): return False if self.jwtHasExpired(jwt): return False (user_profile, jsonp) = self.getUserProfile(jwt) if user_profile == None: return False sessionAttributes = identity.getSessionId( ).getSessionAttributes() self.skipProfileUpdate = StringHelper.equalsIgnoreCase( sessionAttributes.get("skipPassportProfileUpdate"), "true") return self.attemptAuthentication(identity, user_profile, jsonp) #See passportlogin.xhtml provider = ServerUtil.getFirstValue(requestParameters, "loginForm:provider") if StringHelper.isEmpty(provider): #it's username + passw auth print "Passport. authenticate for step 1. Basic authentication detected" logged_in = False credentials = identity.getCredentials() user_name = credentials.getUsername() user_password = credentials.getPassword() if StringHelper.isNotEmptyString( user_name) and StringHelper.isNotEmptyString( user_password): authenticationService = CdiUtil.bean(AuthenticationService) logged_in = authenticationService.authenticate( user_name, user_password) print "Passport. authenticate for step 1. Basic authentication returned: %s" % logged_in return logged_in elif provider in self.registeredProviders: #it's a recognized external IDP identity.setWorkingParameter("selectedProvider", provider) print "Passport. authenticate for step 1. Retrying step 1" #see prepareForStep (step = 1) return True if step == 2: mail = ServerUtil.getFirstValue(requestParameters, "loginForm:email") jsonp = identity.getWorkingParameter("passport_user_profile") if mail == None: self.setMessageError(FacesMessage.SEVERITY_ERROR, "Email was missing in user profile") elif jsonp != None: # Completion of profile takes place user_profile = json.loads(jsonp) user_profile["mail"] = [mail] return self.attemptAuthentication(identity, user_profile, jsonp) print "Passport. authenticate for step 2. Failed: expected mail value in HTTP request and json profile in session" return False
def prepareForStep(self, configurationAttributes, requestParameters, step): extensionResult = self.extensionPrepareForStep(configurationAttributes, requestParameters, step) if extensionResult != None: return extensionResult print "Passport. prepareForStep called %s" % str(step) identity = CdiUtil.bean(Identity) if step == 1: #re-read the strategies config (for instance to know which strategies have enabled the email account linking) self.parseProviderConfigs() identity.setWorkingParameter("externalProviders", json.dumps(self.registeredProviders)) providerParam = self.customAuthzParameter url = None sessionAttributes = identity.getSessionId().getSessionAttributes() self.skipProfileUpdate = StringHelper.equalsIgnoreCase( sessionAttributes.get("skipPassportProfileUpdate"), "true") #this param could have been set previously in authenticate step if current step is being retried provider = identity.getWorkingParameter("selectedProvider") print "prepareForStep %s - provider = %s" % (str(step), str(provider)) # if there is a selectedProvider if provider != None: # get the redirect URL to use at facesService.redirectToExternalURL() that sends /passport/auth/<provider>/<token> url = self.getPassportRedirectUrl(provider) print "prepareForStep %s - url = %s" % (str(step), url) # sets selectedProvider back to None identity.setWorkingParameter("selectedProvider", None) # if there is customAuthzParameter elif providerParam != None: # get it from sessionAtributes paramValue = sessionAttributes.get(providerParam) #if exists if paramValue != None: print "Passport. prepareForStep. Found value in custom param of authorization request: %s" % paramValue provider = self.getProviderFromJson(paramValue) if provider == None: print "Passport. prepareForStep. A provider value could not be extracted from custom authorization request parameter" elif not provider in self.registeredProviders: print "Passport. prepareForStep. Provider '%s' not part of known configured IDPs/OPs" % provider else: url = self.getPassportRedirectUrl(provider) # if no provider selected yet... if url == None: print "Passport. prepareForStep. A page to manually select an identity provider will be shown" # else already got the /passport/auth/<provider>/<token> url... else: facesService = CdiUtil.bean(FacesService) # redirects to Passport getRedirectURL - sends browser to IDP. print "Passport. Redirecting to external url: %s" + url facesService.redirectToExternalURL(url) return True
def authenticate(self, configurationAttributes, requestParameters, step): extensionResult = self.extensionAuthenticate(configurationAttributes, requestParameters, step) if extensionResult != None: return extensionResult print "Passport. authenticate for step %s called" % str(step) identity = CdiUtil.bean(Identity) # Loading self.registeredProviders in case passport destroyed if not hasattr(self, 'registeredProviders'): print "Passport. Fetching registered providers." self.parseProviderConfigs() if step == 1: jwt_param = None if self.isInboundFlow(identity): # if is idp-initiated inbound flow print "Passport. authenticate for step 1. Detected idp-initiated inbound Saml flow" # get request from session attributes jwt_param = identity.getSessionId().getSessionAttributes().get( AuthorizeRequestParam.STATE) print "Passport. authenticate. step ==1. if self.isInboundFlow(identity):." print "jwt_param = %s" % jwt_param # now jwt_param != None if jwt_param == None: print "Entered if jwt_param == None" # gets jwt parameter "user" sent after authentication by passport (if exists) jwt_param = ServerUtil.getFirstValue(requestParameters, "user") if jwt_param != None: # and now that the jwt_param user exists... print "Entered if jwt_param != None" print "Passport. authenticate for step 1. JWT user profile token found" if self.isInboundFlow(identity): jwt_param = base64.urlsafe_b64decode(str(jwt_param + '==')) # Parse JWT and validate jwt = Jwt.parse(jwt_param) if not self.validSignature(jwt): return False if self.jwtHasExpired(jwt): return False # Gets user profile as string and json using the information on JWT (user_profile, jsonp) = self.getUserProfile(jwt) if user_profile == None: return False sessionAttributes = identity.getSessionId( ).getSessionAttributes() self.skipProfileUpdate = StringHelper.equalsIgnoreCase( sessionAttributes.get("skipPassportProfileUpdate"), "true") return self.attemptAuthentication(identity, user_profile, jsonp) #See passportlogin.xhtml print "-------------============------------" provider = ServerUtil.getFirstValue(requestParameters, "loginForm:provider") print "authenticate() - provider = %s" % str(provider) print "authenticate - self.registeredProviders: %s" % str( self.registeredProviders) if StringHelper.isEmpty(provider): #it's username + passw auth print "Passport. authenticate for step 1. Basic authentication detected" logged_in = False credentials = identity.getCredentials() user_name = credentials.getUsername() user_password = credentials.getPassword() if StringHelper.isNotEmptyString( user_name) and StringHelper.isNotEmptyString( user_password): authenticationService = CdiUtil.bean(AuthenticationService) logged_in = authenticationService.authenticate( user_name, user_password) print "Passport. authenticate for step 1. Basic authentication returned: %s" % logged_in return logged_in elif provider in self.registeredProviders: # user selected provider # it's a recognized external IDP identity.setWorkingParameter("selectedProvider", provider) print "Passport. authenticate for step 1. Retrying step 1" #see prepareForStep (step = 1) return True if step == 2: mail = ServerUtil.getFirstValue(requestParameters, "loginForm:email") jsonp = identity.getWorkingParameter("passport_user_profile") if mail == None: self.setMessageError(FacesMessage.SEVERITY_ERROR, "Email was missing in user profile") elif jsonp != None: # Completion of profile takes place user_profile = json.loads(jsonp) user_profile["mail"] = [mail] return self.attemptAuthentication(identity, user_profile, jsonp) print "Passport. authenticate for step 2. Failed: expected mail value in HTTP request and json profile in session" return False
def checkStatus(self, iw_api_uri, iw_service_id, user_name, session_id, without_pin): print "inside check status ", user_name + session_id # step 1: call action=pushAthenticate httpService = CdiUtil.bean(HttpService) request_uri = iw_api_uri + "action=pushAuthenticate" + "&serviceId=" + str( iw_service_id) + "&userId=" + httpService.encodeUrl( user_name) + "&format=json&withoutpin=" + str(without_pin) #curTime = java.lang.System.currentTimeMillis() #endTime = curTime + (timeout * 1000) try: response_status = None http_service_response = httpService.executeGet( self.client, request_uri) http_response = http_service_response.getHttpResponse() if (http_response.getStatusLine().getStatusCode() != 200): print "inWebo. Invalid response from inwebo server: checkStatus ", str( http_response.getStatusLine().getStatusCode()) httpService.consume(http_response) return None response_bytes = httpService.getResponseContent(http_response) response_string = httpService.convertEntityToString(response_bytes) httpService.consume(http_response) except: print "inWebo validate method. Exception: ", sys.exc_info()[1] return False finally: http_service_response.closeConnection() print "response string:", response_string json_response = json.loads(response_string) if StringHelper.equalsIgnoreCase(json_response['err'], "OK"): session_id = json_response['sessionId'] checkResult_uri = iw_api_uri + "action=checkPushResult" + "&serviceId=" + str( iw_service_id) + "&userId=" + httpService.encodeUrl( user_name) + "&sessionId=" + httpService.encodeUrl( session_id) + "&format=json&withoutpin=1" print "checkPushResult_uri:", checkResult_uri startTime = System.currentTimeMillis() currentTime = startTime endTime = startTime + long(25000) print "start time ----> ", startTime print "end time ", endTime while (endTime > currentTime): try: # step 2: call action=checkPushResult; using session id from step 1 http_check_push_response = httpService.executeGet( self.client, checkResult_uri) check_push_response = http_check_push_response.getHttpResponse( ) check_push_response_bytes = httpService.getResponseContent( check_push_response) check_push_response_string = httpService.convertEntityToString( check_push_response_bytes) httpService.consume(check_push_response) check_push_json_response = json.loads( check_push_response_string) print "check_push_json_response :", check_push_json_response if StringHelper.equalsIgnoreCase( check_push_json_response['err'], "OK"): self.push_fail = None return True elif StringHelper.equalsIgnoreCase( check_push_json_response['err'], "NOK:REFUSED"): print "Push request notification for session", session_id self.push_fail = "inwebo.push.notification.rejected" return False elif StringHelper.equalsIgnoreCase( check_push_json_response['err'], "NOK:TIMEOUT"): print "Push request timed out for session", session_id self.push_fail = "inwebo.push.notification.timed.out.for.session" return False elif StringHelper.equalsIgnoreCase( check_push_json_response['err'], "NOK:WAITING"): self.push_fail = "inwebo.push.notification.timed.out.for.session" currentTime = System.currentTimeMillis() print " NOw ######## ", currentTime java.lang.Thread.sleep(5000) continue else: self.push_fail = "inwebo.push.notification.failed" return False finally: http_check_push_response.closeConnection() elif StringHelper.equalsIgnoreCase(json_response['err'], "NOK:SN"): self.push_fail = "inwebo.no.username" return False elif StringHelper.equalsIgnoreCase(json_response['err'], "NOK:account unknown"): self.push_fail = "inwebo.no.username" return False else: print "No response from server." self.push_fail = "inwebo.push.notification.timed.out.for.session" return False print "inWebo. CheckStatus. The process has not received a response from the phone yet" return False