From 964a29a9ff34e723fc7d1dfc2f1031af61b16ffe Mon Sep 17 00:00:00 2001 From: Julian Rother <julianr@fsmpi.rwth-aachen.de> Date: Tue, 6 Oct 2020 21:45:23 +0200 Subject: [PATCH] Replaced manual oauth implementation with python-requests-oauthlib --- app.py | 75 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/app.py b/app.py index a16fc2f..b7aa395 100644 --- a/app.py +++ b/app.py @@ -2,16 +2,16 @@ from functools import wraps import secrets, json import urllib.parse -from flask import Flask, session, request, redirect, abort, render_template, url_for, flash, Response +from flask import Flask, session, request, redirect, abort, url_for, Response -import requests +from requests_oauthlib import OAuth2Session app = Flask(__name__) app.secret_key = b'my secret' app.config['SESSION_COOKIE_NAME'] = 'oauth-session' -app.config['OAUTH2_AUTH_URL'] = 'http://localhost:5001/oauth2/authorize' -app.config['OAUTH2_TOKEN_URL'] = 'http://localhost:5001/oauth2/token' -app.config['OAUTH2_USERINFO_URL'] = 'http://localhost:5001/oauth2/userinfo' +app.config['OAUTH2_AUTH_URL'] = 'https://localhost:5001/oauth2/authorize' +app.config['OAUTH2_TOKEN_URL'] = 'https://localhost:5001/oauth2/token' +app.config['OAUTH2_USERINFO_URL'] = 'https://localhost:5001/oauth2/userinfo' @app.route("/auth") def auth(): @@ -21,37 +21,58 @@ def auth(): resp.headers['REMOTE_USER'] = session['user'] return resp +def get_oauth(**kwargs): + return OAuth2Session(request.headers['X-CLIENT-ID'], + redirect_uri=request.headers['X-REDIRECT-URI'], + scope=request.headers['X-SCOPE'], **kwargs) + @app.route("/login") def login(): - client_id = request.headers['X-CLIENT-ID'] - scope = request.headers['X-SCOPE'] - redirect_uri = request.headers['X-REDIRECT-URI'] - session['oauth-state'] = secrets.token_urlsafe() - session['oauth-ref'] = request.values.get('url', '/') - return redirect(app.config['OAUTH2_AUTH_URL']+'?'+urllib.parse.urlencode({'response_type': 'code', 'client_id': client_id, 'scope': scope, 'state': session['oauth-state'], 'redirect_uri': redirect_uri})) + client = get_oauth() + url, state = client.authorization_url(app.config['OAUTH2_AUTH_URL']) + session['state'] = state + session['url'] = request.values.get('url', '/') + return redirect(url) @app.route("/callback") def callback(): - client_id = request.headers['X-CLIENT-ID'] - client_secret = request.headers['X-CLIENT-SECRET'] - redirect_uri = request.headers['X-REDIRECT-URI'] - code = request.values['code'] - if session.pop('oauth-state') != request.values['state']: - abort(500) - r = requests.request('POST', app.config['OAUTH2_TOKEN_URL'], data={'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri, 'client_id': client_id, 'client_secret': client_secret}) - if r.status_code != 200: - abort(403) - data = r.json() - r = requests.request('GET', app.config['OAUTH2_USERINFO_URL'], headers={'Authorization': 'Bearer %s'%data['access_token']}) - if r.status_code != 200: - abort(403) - session['user'] = r.json()['email'] - return redirect(session.pop('oauth-ref')) + client = get_oauth(state=session.pop('state')) + token = client.fetch_token(app.config['OAUTH2_TOKEN_URL'], client_secret=request.headers['X-CLIENT-SECRET'], authorization_response=request.url, verify=False) + userinfo = client.get(app.config['OAUTH2_USERINFO_URL']).json() + session['user'] = userinfo['email'] + return redirect(session.pop('url')) @app.route("/logout") def logout(): session.clear() return 'Ok', 200 +@app.route("/status") +def status(): + resp = Response('''Proxy Configuration Status + +For this proxy service to work properly, the OAuth client crendentials must +be injected in by the webserver as HTTP-headers: + +X-CLIENT-ID: %s +X-CLIENT-SECRET: %s +X-REDIRECT-URI: %s + +If you accessed this ressource with the URL + + https://mydomain/mysubpath/info + +then the redirect URI must be set to: + + https://mydomain/mysubpath/callback + +This exact redirect URI must also be registered with the OAuth server as +a valid redirect_uri for the client_id. +'''%(request.headers.get('X-CLIENT-ID', '(unset)'), + '(set)' if request.headers.get('X-CLIENT-SECRET') else '(unset)', + request.headers.get('X-REDIRECT-URI', '(unset)'))) + resp.mimetype = 'text/plain; charset=utf-8' + return resp + if __name__ == '__main__': - app.run(port=5002) + app.run(debug=True, host='localhost', port=5002, ssl_context='adhoc') -- GitLab