Skip to content
Snippets Groups Projects
Commit ff765a90 authored by jan.bednarik's avatar jan.bednarik
Browse files

Fix OpenID Connect login workflow.

parent 7b5cd1a6
No related branches found
No related tags found
No related merge requests found
...@@ -42,9 +42,6 @@ class Login(relay.ClientIDMutation): ...@@ -42,9 +42,6 @@ class Login(relay.ClientIDMutation):
client_id=client.client_id, client_id=client.client_id,
client_secret=client.client_secret, client_secret=client.client_secret,
issuer=client.provider_info['issuer'], issuer=client.provider_info['issuer'],
authorization_endpoint=client.provider_info['authorization_endpoint'],
token_endpoint=client.provider_info['token_endpoint'],
userinfo_endpoint=client.provider_info['userinfo_endpoint'],
) )
# prepare login attempt details # prepare login attempt details
......
from django.conf import settings from django.conf import settings
from oic.oic import Client from oic.oic import Client
from oic.oic.message import ( from oic.oic.message import (
ProviderConfigurationResponse,
RegistrationResponse, RegistrationResponse,
ClaimsRequest, ClaimsRequest,
Claims, Claims,
...@@ -18,15 +17,14 @@ def init_client_for_uid(openid_uid): ...@@ -18,15 +17,14 @@ def init_client_for_uid(openid_uid):
def init_client_for_shortcut(openid_client_obj): def init_client_for_shortcut(openid_client_obj):
client = Client(client_authn_method=CLIENT_AUTHN_METHOD) client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
set_registration_info(client, openid_client_obj.client_id, reg_info = {
openid_client_obj.client_secret, settings.REDIRECT_URI) 'client_id': openid_client_obj.client_id,
info = { 'client_secret': openid_client_obj.client_secret,
'issuer': openid_client_obj.issuer, 'redirect_uris': [settings.REDIRECT_URI],
'authorization_endpoint': openid_client_obj.authorization_endpoint,
'token_endpoint': openid_client_obj.token_endpoint,
'userinfo_endpoint': openid_client_obj.userinfo_endpoint,
} }
client.provider_info = ProviderConfigurationResponse(**info) client_reg = RegistrationResponse(**reg_info)
client.store_registration_info(client_reg)
client.provider_config(openid_client_obj.issuer)
return client return client
...@@ -43,7 +41,7 @@ def get_authorization_url(client, state): ...@@ -43,7 +41,7 @@ def get_authorization_url(client, state):
args = { args = {
'client_id': client.client_id, 'client_id': client.client_id,
'response_type': 'code', 'response_type': 'code',
'scope': ['openid'], 'scope': 'openid',
'state': state, 'state': state,
'redirect_uri': client.registration_response['redirect_uris'][0], 'redirect_uri': client.registration_response['redirect_uris'][0],
'claims': ClaimsRequest(userinfo=Claims( 'claims': ClaimsRequest(userinfo=Claims(
...@@ -53,27 +51,9 @@ def get_authorization_url(client, state): ...@@ -53,27 +51,9 @@ def get_authorization_url(client, state):
} }
auth_req = client.construct_AuthorizationRequest(request_args=args) auth_req = client.construct_AuthorizationRequest(request_args=args)
url = auth_req.request(client.provider_info['authorization_endpoint']) return auth_req.request(client.provider_info['authorization_endpoint'])
return url
def set_registration_info(client, client_id, client_secret, redirect_uri):
info = {
'client_id': client_id,
'client_secret': client_secret,
'redirect_uris': [redirect_uri],
}
client_reg = RegistrationResponse(**info)
client.store_registration_info(client_reg)
return client
def do_access_token_request(client, code, state): def do_access_token_request(client, code, state):
args = { args = {'code': code, 'redirect_uri': settings.REDIRECT_URI}
'code': code,
'client_id': client.client_id,
'client_secret': client.client_secret,
'redirect_uri': client.registration_response['redirect_uris'][0],
'token_endpoint': client.provider_info['token_endpoint'],
}
client.do_access_token_request(state=state, request_args=args) client.do_access_token_request(state=state, request_args=args)
from django.shortcuts import redirect
from django.views import View
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
import time
import urllib.parse
from oic.oic.message import AuthorizationResponse
from .models import LoginAttempt
from .openid import (
init_client_for_shortcut,
do_access_token_request,
)
class IndexView(TemplateView): class IndexView(TemplateView):
template_name = 'core/index.html' template_name = 'core/index.html'
class LoginRedirectView(View):
def get(self, request, **kwargs):
query_string = request.META['QUERY_STRING']
# get state from query string
state = urllib.parse.parse_qs(query_string)['state'][0]
# get login attempt
la = LoginAttempt.objects.select_related().get(state=state)
# delete login attempt so it can be used just once
la.delete()
# check login attempt expiration
if la.expiration < time.time():
# TODO redirect to app_redirect_uri with fail
raise NotImplementedError
# reconstruct OpenID Client
client = init_client_for_shortcut(la.openid_client)
# process query string from OpenID redirect
aresp = client.parse_response(AuthorizationResponse, info=query_string,
sformat='urlencoded')
code = aresp['code']
state = aresp['state']
# OpenID access token request
do_access_token_request(client, code, state)
# OpenID user info request
user_info = client.do_user_info_request(state=state)
print('\nUSER INFO:', user_info, '\n')
# TODO get or create User
# TODO create session
# expiration = get_session_expiration_time()
# TODO create access token for session
# token = create_access_token(session.meta.id, expiration)
# TODO add token
return redirect(la.app_redirect_uri)
...@@ -2,10 +2,11 @@ from django.contrib import admin ...@@ -2,10 +2,11 @@ from django.contrib import admin
from django.urls import path from django.urls import path
from graphene_django.views import GraphQLView from graphene_django.views import GraphQLView
from openlobby.core.views import IndexView from openlobby.core.views import IndexView, LoginRedirectView
urlpatterns = [ urlpatterns = [
path('', IndexView.as_view(), name='index'), path('', IndexView.as_view(), name='index'),
path('login-redirect', LoginRedirectView.as_view(), name='login-redirect'),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('graphql', GraphQLView.as_view(graphiql=True)), path('graphql', GraphQLView.as_view(graphiql=True)),
] ]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment