Created
November 16, 2017 11:00
-
-
Save jmhale/5c6034276436c5843591c1709b68ba03 to your computer and use it in GitHub Desktop.
Handles MFA auth to Okta and outputs session_token
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" Handles auth to Okta and return session_token """ | |
#pylint: disable=C0325 | |
import os | |
from ConfigParser import RawConfigParser | |
from getpass import getpass | |
import requests | |
class OktaAuth(object): | |
""" Handles auth to Okta and returns SAML assertion """ | |
def __init__(self, okta_profile, verbose): | |
home_dir = os.path.expanduser('~') | |
okta_config = home_dir + '/.okta-aws' | |
parser = RawConfigParser() | |
parser.read(okta_config) | |
profile = okta_profile | |
if parser.has_option(profile, 'base-url'): | |
self.base_url = "https://%s" % parser.get(profile, 'base-url') | |
else: | |
print("No base-url set in ~/.okta-aws") | |
if parser.has_option(profile, 'username'): | |
self.username = parser.get(profile, 'username') | |
if verbose: | |
print("Authenticating as: %s" % self.username) | |
else: | |
self.username = raw_input('Enter username: ') | |
if parser.has_option(profile, 'password'): | |
self.password = parser.get(profile, 'password') | |
else: | |
self.password = getpass('Enter password: ') | |
self.verbose = verbose | |
def primary_auth(self): | |
""" Performs primary auth against Okta """ | |
auth_data = { | |
"username": self.username, | |
"password": self.password | |
} | |
resp = requests.post(self.base_url+'/api/v1/authn', json=auth_data) | |
resp_json = resp.json() | |
if 'status' in resp_json: | |
if resp_json['status'] == 'MFA_REQUIRED': | |
factors_list = resp_json['_embedded']['factors'] | |
state_token = resp_json['stateToken'] | |
session_token = self.verify_mfa(factors_list, state_token) | |
elif resp_json['status'] == 'SUCCESS': | |
session_token = resp_json['sessionToken'] | |
elif resp.status_code != 200: | |
print(resp_json['errorSummary']) | |
exit(1) | |
else: | |
print(resp_json) | |
exit(1) | |
return session_token | |
def verify_mfa(self, factors_list, state_token): | |
""" Performs MFA auth against Okta """ | |
if len(factors_list) == 1: | |
session_token = self.verify_single_factor(factors_list[0]['id'], state_token) | |
else: | |
supported_factors = [] | |
for factor in factors_list: | |
if factor['factorType'] == "token:software:totp": | |
supported_factors.append(factor) | |
print("Registered MFA factors:") | |
for index, factor in enumerate(supported_factors): | |
factor_type = factor['factorType'] | |
factor_provider = factor['provider'] | |
if factor_provider == "GOOGLE": | |
factor_name = "Google Authenticator" | |
elif factor_provider == "OKTA": | |
if factor_type == "push": | |
factor_name = "Okta Verify - Push" | |
else: | |
factor_name = "Okta Verify" | |
else: | |
factor_name = "Unsupported factor type: %s" % factor_provider | |
print("%d: %s" % (index+1, factor_name)) | |
factor_choice = input('Please select the MFA factor: ') | |
if self.verbose: | |
print("Performing secondary authentication using: %s" % | |
supported_factors[factor_choice-1]['provider']) | |
session_token = self.verify_single_factor(supported_factors[factor_choice-1]['id'], | |
state_token) | |
return session_token | |
def verify_single_factor(self, factor_id, state_token): | |
""" Verifies a single MFA factor """ | |
factor_answer = raw_input('Enter MFA token: ') | |
req_data = { | |
"stateToken": state_token, | |
"answer": factor_answer | |
} | |
post_url = "%s/api/v1/authn/factors/%s/verify" % (self.base_url, factor_id) | |
resp = requests.post(post_url, json=req_data) | |
resp_json = resp.json() | |
if 'status' in resp_json: | |
if resp_json['status'] == "SUCCESS": | |
return resp_json['sessionToken'] | |
elif resp.status_code != 200: | |
print(resp_json['errorSummary']) | |
exit(1) | |
else: | |
print(resp_json) | |
exit(1) | |
OKTA = OktaAuth("default", True) | |
SESSION_TOKEN = OKTA.primary_auth() | |
print SESSION_TOKEN |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment