Skip to content
Snippets Groups Projects
Commit 2160f634 authored by Luka's avatar Luka
Browse files

Implemented oidc with hydra

parent 26ffb28a
No related branches found
No related tags found
No related merge requests found
......@@ -13,10 +13,12 @@ from areas import auth
from helpers import (
BadRequest,
KratosError,
HydraError,
bad_request_error,
validation_error,
kratos_error,
global_error,
hydra_error,
)
from config import *
......@@ -30,6 +32,7 @@ app.register_error_handler(Exception, global_error)
app.register_error_handler(BadRequest, bad_request_error)
app.register_error_handler(ValidationError, validation_error)
app.register_error_handler(KratosError, kratos_error)
app.register_error_handler(HydraError, hydra_error)
jwt = JWTManager(app)
......
from flask import request, jsonify
from flask import jsonify
from flask_jwt_extended import create_access_token
from flask_cors import cross_origin
from datetime import timedelta
from areas import api_v1
from config import *
from helpers import HydraOauth
USERNAME = 'admin'
PASSWORD = 'admin'
@api_v1.route('/login', methods=['POST'])
@api_v1.route("/login", methods=["POST"])
@cross_origin()
def login():
username = request.json.get('username')
password = request.json.get('password')
authorization_url = HydraOauth.authorize()
return jsonify({"authorizationUrl": authorization_url})
if username != USERNAME or password != PASSWORD:
return jsonify({'errorMessage': 'Invalid username or password'}), 401
@api_v1.route("/hydra/callback")
@cross_origin()
def hydra_callback():
token = HydraOauth.get_token()
access_token = create_access_token(
identity=token, expires_delta=timedelta(days=365)
)
access_token = create_access_token(identity=username)
return jsonify({'username': USERNAME, 'access_token': access_token})
return jsonify({"access_token": access_token})
import os
SECRET_KEY = os.environ.get('SECRET_KEY')
KRATOS_URL = os.environ.get('KRATOS_URL')
SECRET_KEY = os.environ.get("SECRET_KEY")
KRATOS_URL = os.environ.get("KRATOS_URL")
HYDRA_CLIENT_ID = os.environ.get("HYDRA_CLIENT_ID")
HYDRA_CLIENT_SECRET = os.environ.get("HYDRA_CLIENT_SECRET")
HYDRA_AUTHORIZATION_BASE_URL = os.environ.get("HYDRA_AUTHORIZATION_BASE_URL")
TOKEN_URL = os.environ.get("TOKEN_URL")
from .kratos_api import *
from .error_handler import *
from .hydra_oauth import *
......@@ -6,6 +6,10 @@ class KratosError(Exception):
pass
class HydraError(Exception):
pass
class BadRequest(Exception):
pass
......@@ -24,11 +28,17 @@ def validation_error(e):
def kratos_error(e):
message = e.args[0] if e.args else "Failed to contact Kratos."
message = "[KratosError] " + e.args[0] if e.args else "Failed to contact Kratos."
status_code = e.args[1] if e.args else 500
return jsonify({"errorMessage": message}), status_code
def hydra_error(e):
message = "[HydraError] " + e.args[0] if e.args else "Failed to contact Hydra."
status_code = e.args[1] if e.args else 500
return jsonify({"errorMessage": message}), status_code
def global_error(e):
message = str(e)
return jsonify({"errorMessage": message})
return jsonify({"errorMessage": message}), 500
from flask import request, session
from requests_oauthlib import OAuth2Session
from config import *
from helpers import HydraError
class HydraOauth:
SESSION_KEY = "oauth_state"
@staticmethod
def authorize():
try:
hydra = OAuth2Session(HYDRA_CLIENT_ID)
authorization_url, state = hydra.authorization_url(
HYDRA_AUTHORIZATION_BASE_URL
)
# State is used to prevent CSRF, keep this for later.
session[HydraOauth.SESSION_KEY] = state
return authorization_url
except Exception as err:
raise HydraError(str(err), 500)
@staticmethod
def get_token():
try:
hydra = OAuth2Session(
HYDRA_CLIENT_ID, state=session[HydraOauth.SESSION_KEY]
)
token = hydra.fetch_token(
TOKEN_URL,
client_secret=HYDRA_CLIENT_SECRET,
authorization_response=request.url,
)
session["hydra_token"] = token
return token
except Exception as err:
raise HydraError(str(err), 500)
......@@ -18,6 +18,8 @@ class KratosApi:
res = requests.get("{}{}".format(KRATOS_URL, url))
KratosApi.__handleError(res)
return res
except KratosError as err:
raise err
except:
raise KratosError()
......
......@@ -17,6 +17,7 @@ jsonschema==4.3.2
Jinja2==3.0.3
MarkupSafe==2.0.1
mypy-extensions==0.4.3
oauthlib==3.1.1
pathspec==0.9.0
platformdirs==2.4.0
pycparser==2.21
......@@ -24,6 +25,7 @@ PyJWT==2.3.0
pyrsistent==0.18.0
regex==2021.11.10
requests==2.26.0
requests-oauthlib==1.3.0
six==1.16.0
tomli==1.2.3
typing-extensions==4.0.1
......
......@@ -22,5 +22,8 @@ export FLASK_APP=app.py
export FLASK_ENV=development
export SECRET_KEY="e38hq!@0n64g@qe6)5csk41t=ljo2vllog(%k7njnm4b@kh42c"
export KRATOS_URL="http://127.0.0.1:8000"
export HYDRA_CLIENT_ID="dashboard"
export HYDRA_CLIENT_SECRET="BrYRtKygtrcwGHviUSqybvFTgfnaZgPh"
export HYDRA_AUTHORIZATION_BASE_URL="https://sso.init.stackspin.net/oauth2/auth"
export TOKEN_URL="https://sso.init.stackspin.net/oauth2/token"
flask run
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment