Skip to content

Instantly share code, notes, and snippets.

@lorne-luo
Created May 2, 2019 05:04
Show Gist options
  • Save lorne-luo/c60f87a2f3ef67cd71586f179eb8147e to your computer and use it in GitHub Desktop.
Save lorne-luo/c60f87a2f3ef67cd71586f179eb8147e to your computer and use it in GitHub Desktop.
oauth with python
import requests
import json
import uuid
from flask_oauthlib.client import OAuthRemoteApp
from flask_oauthlib.utils import to_bytes
from jose import jws
from oauthlib.oauth2 import WebApplicationClient
try:
from urlparse import urljoin
import urllib2 as http
except ImportError:
from urllib import request as http
from urllib.parse import urljoin
tenant_id = 'fabrikamb2c.onmicrosoft.com'
client_id = 'fdb91ff5-5ce6-41f3-bdbd-8267c817015d'
client_secret = r'X330F3#92!z614M4'
policy_name = 'b2c_1_susi'
core_url = 'https://login.microsoftonline.com/tfp/' + tenant_id + '/' + policy_name
token_url = core_url + '/oauth2/v2.0/token'
authorize_url = core_url + '/oauth2/v2.0/authorize'
keys_url = core_url + '/discovery/keys'
scopes = 'openid ' + client_id
redirect_uri = 'http://localhost:5000/login/authorized'
guid = str(uuid.uuid4()) # guid to do a validation that the authentication is send from here
# step 1. build the launch url, then request it
client = WebApplicationClient(client_id)
url = client.prepare_request_uri(
'https://login.microsoftonline.com/tfp/fabrikamb2c.onmicrosoft.com/b2c_1_susi/oauth2/v2.0/authorize',
redirect_uri=redirect_uri,
scope=scopes,
state=guid,
)
print(url)
# https://login.microsoftonline.com/tfp/fabrikamb2c.onmicrosoft.com/b2c_1_susi/oauth2/v2.0/authorize?response_type=code&client_id=fdb91ff5-5ce6-41f3-bdbd-8267c817015d&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Flogin%2Fauthorized&scope=openid+fdb91ff5-5ce6-41f3-bdbd-8267c817015d&state=7b9f3c85-53b0-4d3c-b7d6-47906b5b5be7
# step 2. Ms will callback our `redirect_url`
# http://localhost:5000/login/authorized?state=7b9f3c85-53b0-4d3c-b7d6-47906b5b5be7&code=eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMCIsInppcCI6IkRlZmxhdGUiLCJzZXIiOiIxLjAifQ..pKQq4c_xF6XP8gGI.EDpMil0Dz4E6kYPZF1y_g5leOPaaF1pIiwfgte6-W5GOlSiwi6Iqd1GHkjwSlvGWfAekhBONFWp4sJuKhe62D59W9cZgR9rmVNfPUTghvkV9kZuU7Qgss07n6XLAWkfB0Fb5-MLvnihtWn4aqoeb1o_H0O-uUzVZIne7RmgWCgWsNyG1VCLyPqoFCVCTUuZeOTxy1GX46U_jTLzzE6ohr-j-yfAFpqUpp-EpNFANghow_DIdNvHfgf1d1ZRQyVFMkTy9lP4OJdZIyzSd3ygtoUIu1NepFNpfchjAGqkY3wxuHQyCO-hv9Qh37-ZCzykoKIyXgavqzNzcJjXO_Df7P-CaTk7YHn31AlhfekgGZubtP0vht_zlokZMJ5mELylRkIkvBUR7k8xEtvNwnLYjOjyfqirAiDtVBoN4nrRUG8VjPedKSyicfWNuv5z6MEjWWbjlg5TWdVCctrXlNLiz2JWFoP41bH3yTpr_eNYpnQ-AM9trMPQYmTnY9kaNrPQvfv17mCaCMg37LI8H3OBJX1fafXn5AaUZSAfTi0E4TCQAqK88dUQHealP1B1DefFyJhMI
# parse the `code` querystring
callback_url = 'http://localhost:5000/login/authorized?state=7b9f3c85-53b0-4d3c-b7d6-47906b5b5be7&code=eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMCIsInppcCI6IkRlZmxhdGUiLCJzZXIiOiIxLjAifQ..pKQq4c_xF6XP8gGI.EDpMil0Dz4E6kYPZF1y_g5leOPaaF1pIiwfgte6-W5GOlSiwi6Iqd1GHkjwSlvGWfAekhBONFWp4sJuKhe62D59W9cZgR9rmVNfPUTghvkV9kZuU7Qgss07n6XLAWkfB0Fb5-MLvnihtWn4aqoeb1o_H0O-uUzVZIne7RmgWCgWsNyG1VCLyPqoFCVCTUuZeOTxy1GX46U_jTLzzE6ohr-j-yfAFpqUpp-EpNFANghow_DIdNvHfgf1d1ZRQyVFMkTy9lP4OJdZIyzSd3ygtoUIu1NepFNpfchjAGqkY3wxuHQyCO-hv9Qh37-ZCzykoKIyXgavqzNzcJjXO_Df7P-CaTk7YHn31AlhfekgGZubtP0vht_zlokZMJ5mELylRkIkvBUR7k8xEtvNwnLYjOjyfqirAiDtVBoN4nrRUG8VjPedKSyicfWNuv5z6MEjWWbjlg5TWdVCctrXlNLiz2JWFoP41bH3yTpr_eNYpnQ-AM9trMPQYmTnY9kaNrPQvfv17mCaCMg37LI8H3OBJX1fafXn5AaUZSAfTi0E4TCQAqK88dUQHealP1B1DefFyJhMI'
data = client.parse_request_uri_response(callback_url, state=guid)
request_body = client.prepare_request_body(code=data.get('code'),
redirect_uri=redirect_uri,
client_secret=client_secret)
remote_args = {
'code': data.get('code'),
'client_secret': client_secret,
'redirect_uri': redirect_uri
}
# remote_args.update(self.access_token_params)
headers = {}
headers.update({'Content-Type': 'application/x-www-form-urlencoded'})
body = client.prepare_request_body(**remote_args)
resp, content = OAuthRemoteApp.http_request(
token_url,
headers=headers,
data=to_bytes(body, 'utf-8'),
method='POST',
)
# step 3. decode access_token and get user email
access_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1jNTdkTzZRR1RWQndhTmsifQ.eyJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vNzc1NTI3ZmYtOWEzNy00MzA3LThiM2QtY2MzMTFmNThkOTI1L3YyLjAvIiwiZXhwIjoxNTU2Nzc2NzE2LCJuYmYiOjE1NTY3NzMxMTYsImF1ZCI6ImZkYjkxZmY1LTVjZTYtNDFmMy1iZGJkLTgyNjdjODE3MDE1ZCIsIm9pZCI6Ijc4MzlmNTU5LWYzMDQtNDlmMi04NTdiLTk5MmEyOGVmZGRhOSIsInN1YiI6Ijc4MzlmNTU5LWYzMDQtNDlmMi04NTdiLTk5MmEyOGVmZGRhOSIsIm5hbWUiOiJMb3JuZSIsImpvYlRpdGxlIjoiRGV2IiwiY2l0eSI6Ik1lbGJvdXJuZSIsImVtYWlscyI6WyJsb3JuZS5sdW9AYnV0dGVyZmx5LmNvbS5hdSJdLCJhenAiOiJmZGI5MWZmNS01Y2U2LTQxZjMtYmRiZC04MjY3YzgxNzAxNWQiLCJ2ZXIiOiIxLjAiLCJpYXQiOjE1NTY3NzMxMTZ9.PltSEZWEXBr4RzST8Jjww6CYt_xH7Jl9ZuXCq3DJANBxftAd9gFU65RE1Irvx8wIBfH9andXO6LRyvbMtq5_GGUnmgRaTDKYb99fwLtiJxs9oIAqE0pxTcFixYs6_E-oKY7FeK7e_eSBUg1mJMJh2_JvnNEC2-ygaN58JjPsryFGu5Q4AFdB6IEVNpoGzEDpkLvXtw41LwlqHduVQ0ef6693m6nOZXOcs9v-02rd7jidIEj2SL6XBLcusiT6pvqr_kiI7LNolHmAdm-rvRQcz81_ogyzRFzJYBJ2LfDcE4x91aqCjBlmsgChrMLScDoWK6SiD8_wXykkPxqcX9hUHA"
keys_raw = requests.get(keys_url).text
keys = json.loads(keys_raw)
user_profile=json.loads(jws.verify(access_token, keys, algorithms=['RS256']))
# >>> user_profile
# {'iss': 'https://login.microsoftonline.com/775527ff-9a37-4307-8b3d-cc311f58d925/v2.0/', 'exp': 1556776716, 'nbf': 1556773116, 'aud': 'fdb91ff5-5ce6-41f3-bdbd-8267c817015d', 'oid': '7839f559-f304-49f2-857b-992a28efdda9', 'sub': '7839f559-f304-49f2-857b-992a28efdda9', 'name': 'Lorne', 'jobTitle': 'Dev', 'city': 'Melbourne', 'emails': ['[email protected]'], 'azp': 'fdb91ff5-5ce6-41f3-bdbd-8267c817015d', 'ver': '1.0', 'iat': 1556773116}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment