forked from fatlotus/uchicago-oidc-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
basic_client.py
123 lines (93 loc) · 3.59 KB
/
basic_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""
This application demonstrates the basic flow for a simple consumer of OpenID
Connect.
To authenticate the user, the application redirects to the login server, which
prompts the user for a CNetID, and redirects back, passing an authorization code
as a URL parameter. The application then exchanges the authorization code for a
longer-lived authorization token, which it then uses to read basic profile
information.
In order to run this example properly, you will need to register the application
at the production OpenID Connect server:
1. Visit https://openidcdev.uchicago.edu.
2. Click on "Self-Service Client Registration."
3. Enter "https://localhost:5000" for the Redirect URI, and click Submit.
4. Make note of the client ID and secret, and replace the values in config.py.
Next, install the Flask and requests modules. This can be done by running-
$ pip install -r requirements.txt
-in a terminal. Finally, launch the application-
$ python basic_client.py
-and visit http://localhost:5000 in a web browser.
"""
from flask import Flask, request, redirect, jsonify
import requests.auth, urllib
from config import CLIENT_ID, SECRET
app = Flask(__name__)
def make_url(base, **url_parameters):
"""
Generates a UChicago-specific URI for the given request.
Args:
base: What endpoint, on the OpenID Connect server, to use.
url_parameters: Key-value pair dictionary of GET parameters.
Returns:
The full URL for the request.
"""
return ("https://openidcdev.uchicago.edu" + base + "?" +
urllib.urlencode(url_parameters))
def get_token(code):
"""
Converts a short-lived auth code into a longer-lived auth token.
Args:
code: The authentication code retrieved from the initial redirect.
Returns:
The authentication token, usable for future API requests.
"""
client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, SECRET)
post_data = {"grant_type": "authorization_code",
"code": code,
"redirect_uri": "http://localhost:5000"}
response = requests.post(make_url("/token"),
auth=client_auth,
data=post_data)
token_json = response.json()
return token_json["access_token"]
def get_user_info(access_token):
"""
Returns basic profile information about the user.
Args:
access_token: The auth code returned from get_token(...).
Returns:
A dictionary containing a series of string keys. For example:
{
"email": "[email protected]",
"email_verified": true,
"family_name": "Schmo",
"given_name": "Joe",
"middle_name": "T",
"name": "Joe L Schmo",
"preferred_username": "[email protected]",
"sub": "[email protected]"
}
"""
headers = {"Authorization": "bearer " + access_token}
response = requests.get(make_url("/userinfo"), headers=headers)
return response.json()
@app.route("/")
def home_page():
"""
A Flask web handler to read and output the data available in the OpenID
Connect Userinfo endpoint.
"""
code = request.args.get("code")
token = request.args.get("token")
if token:
return jsonify(get_user_info(token))
elif code:
return redirect("/?" +
urllib.urlencode(dict(token=get_token(code))))
else:
return redirect(make_url("/authorize",
response_type = "code",
client_id = CLIENT_ID,
redirect_uri = "http://localhost:5000"))
if __name__ == "__main__":
app.run(debug=True)