def handle_mfa(self, auth_response): factor_id = auth_response.json()["_embedded"]['factors'][0]['id'] verify_response = validate_response( requests.post( 'https://%s/api/v1/authn/factors/%s/verify' % (self.okta_org_host, factor_id), json={"stateToken": auth_response.json()['stateToken']})) duo_host = verify_response.json( )['_embedded']['factor']['_embedded']['verification']['host'] duo_signature = verify_response.json( )['_embedded']['factor']['_embedded']['verification']['signature'] duo_callback_url = \ verify_response.json()['_embedded']['factor']['_embedded']['verification']['_links']['complete']['href'] duo_mfa = DuoMFA(duo_host) duo_signature_response = duo_mfa.authenticate( "https://%s/signin/verify/duo/web" % self.okta_org_host, duo_signature) duo_response_to_okta_data = { "id": factor_id, "stateToken": auth_response.json()['stateToken'], "sig_response": duo_signature_response } validate_response( requests.post(duo_callback_url, data=duo_response_to_okta_data)) return factor_id
def login_saml2art(config: SAML2ArtConfig, args): password = args.Password if not password: password = get_keychain_password(config.username) else: set_keychain_password(config.username, password) idp = OktaIdP(config.okta_org_host) print("Authenticating to the IdP service...") idp.authenticate(config.username, password) saml_assertion = idp.get_saml_assertion(config.okta_app_url) # create a session to preserve cookies art_session = requests.Session() # ignore .netrc art_session.trust_env = False print("Authenticating to Artifactory...") validate_response( art_session.post('https://%s/ui/api/v1/auth/saml/loginResponse' % config.art_org_host, data={ "SAMLResponse": saml_assertion, "RelayState": "" }, allow_redirects=False), [302]) reauth_token = str( b64encode(("%s:null" % config.username).encode("UTF-8")), "UTF-8") existing_tokens_response = art_session.get( 'https://%s/ui/api/v1/ui/oauth/user/tokens' % config.art_org_host, headers={"X-Requested-With": "artUI"}) create_method = "POST" if (len(existing_tokens_response.json()) > 0) and (existing_tokens_response.json()[0] == "apiKey"): create_method = "PUT" print("Generating API Key...") create_api_key_response = art_session.request( method=create_method, url='https://%s/ui/api/v1/ui/userApiKey' % config.art_org_host, params={ "username": config.username, "realm": "saml" }, json={"username": config.username}, headers={ "X-Requested-With": "artUI", "X-JFrog-Reauthentication": "Basic " + reauth_token }) api_key = create_api_key_response.json()["apiKey"] print("Exporting APIKey...") NetrcExporter().export("~/.netrc", config.art_org_host, config.username, api_key)
def get_saml_assertion(self, redirectUrl): okta_session_redirect_url = "https://%s/login/sessionCookieRedirect" % self.okta_org_host redirect_response = validate_response( requests.get(okta_session_redirect_url, params={ "checkAccountSetupComplete": "true", "token": self.okta_session_token, "redirectUrl": redirectUrl })) return lxmhtml.fromstring(redirect_response.content).xpath( '//input[@name="SAMLResponse"]/@value')[0]
def authenticate(self, user, pwd): auth_response = validate_response( requests.post('https://%s/api/v1/authn' % self.okta_org_host, json={ "username": user, "password": pwd })) auth_status = auth_response.json()['status'] if auth_status == 'SUCCESS': self.okta_session_token = auth_response.json()['sessionToken'] print("Authenticated!") elif auth_status == 'MFA_REQUIRED': factor_id = self.handle_mfa(auth_response) verify_data = {"stateToken": auth_response.json()['stateToken']} okta_verify_url = 'https://%s/api/v1/authn/factors/%s/verify' % ( self.okta_org_host, factor_id) verify_response = validate_response( requests.post(okta_verify_url, json=verify_data)) self.okta_session_token = verify_response.json()['sessionToken'] else: raise Exception("Error: Got [%s] auth status" % auth_status)
def authenticate(self, referral_url, duoSignature): duo_auth_url = "https://%s/frame/web/v1/auth" % self.duo_host duo_signatures = duoSignature.split(":") initialize_data = { "parent": referral_url, "java_version": "", "flash_version": "", "screen_resolution_width": "3008", "screen_resolution_height": "1692", "color_depth": "24", "tx": duo_signatures[0] } duo_auth_response = validate_response( requests.post(duo_auth_url, data=initialize_data)) duo_sid = self.extract_sid(duo_auth_response) duo_push_url = "https://%s/frame/prompt" % self.duo_host duo_push_data = { "sid": duo_sid, "device": "phone1", "factor": "Duo Push", "out_of_date": "false" } duo_auth_response = validate_response( requests.post(duo_push_url, data=duo_push_data)) duoTxStat = duo_auth_response.json()['stat'] duo_tx_id = duo_auth_response.json()['response']['txid'] duo_status_url = "https://%s/frame/status" % self.duo_host duo_status_data = {"sid": duo_sid, "txid": duo_tx_id} duo_status_response = requests.post(duo_status_url, data=duo_status_data) duoTxResult = duo_status_response.json()['response'].get( 'result', None) duoResultURL = duo_status_response.json()['response'].get( 'result_url', None) print(duo_status_response.json()['response']['status']) if duoTxResult != "SUCCESS": while True: sleep(3) duo_status_response = requests.post(duo_status_url, data=duo_status_data) duoTxResult = duo_status_response.json()['response'].get( 'result', None) duoResultURL = duo_status_response.json()['response'].get( 'result_url', None) print(duo_status_response.json()['response']['status']) if duoTxResult == "FAILURE": # TODO Throw! pass if duoTxResult == "SUCCESS": break duoResultURL = ("https://%s%s" % (self.duo_host, duoResultURL)) duoResultResponse = requests.post(duoResultURL, data=duo_status_data) duo_tx_cookie = duoResultResponse.json()['response']['cookie'] return "%s:%s" % (duo_tx_cookie, duo_signatures[1])