oidc auth: get rid of pyoidc (oid) - provide random and crypt functionality in scopes.util
This commit is contained in:
parent
950fcb4174
commit
f911dbf590
2 changed files with 48 additions and 11 deletions
|
@ -2,16 +2,18 @@
|
||||||
|
|
||||||
from email.utils import formatdate
|
from email.utils import formatdate
|
||||||
import json
|
import json
|
||||||
from oic import oic, rndstr, unreserved
|
#from oic import oic, rndstr, unreserved
|
||||||
from oic.oic.message import AuthorizationResponse
|
#from oic.oic.message import AuthorizationResponse
|
||||||
import requests
|
import requests
|
||||||
from time import time
|
from time import time
|
||||||
|
from urllib.parse import urlencode
|
||||||
from zope.authentication.interfaces import IAuthentication
|
from zope.authentication.interfaces import IAuthentication
|
||||||
from zope.interface import implementer
|
from zope.interface import implementer
|
||||||
from zope.publisher.interfaces import Unauthorized
|
from zope.publisher.interfaces import Unauthorized
|
||||||
|
|
||||||
from scopes.server.browser import DefaultView, register
|
from scopes.server.browser import DefaultView, register
|
||||||
from scopes.storage.folder import DummyFolder, Root
|
from scopes.storage.folder import DummyFolder, Root
|
||||||
|
from scopes import util
|
||||||
|
|
||||||
import config
|
import config
|
||||||
|
|
||||||
|
@ -67,24 +69,28 @@ class Authenticator(DummyFolder):
|
||||||
req = self.request
|
req = self.request
|
||||||
print('*** login', self, req.getTraversalStack(), req['PATH_INFO'])
|
print('*** login', self, req.getTraversalStack(), req['PATH_INFO'])
|
||||||
#print('***', dir(req))
|
#print('***', dir(req))
|
||||||
client = oic.Client()
|
#client = oic.Client()
|
||||||
#providerInfo = client.provider_config(config.oidc_provider)
|
#providerInfo = client.provider_config(config.oidc_provider)
|
||||||
#print('***', providerInfo)
|
#print('***', providerInfo)
|
||||||
state = rndstr()
|
state = util.rndstr()
|
||||||
nonce = rndstr()
|
nonce = util.rndstr()
|
||||||
|
codeVerifier = util.rndstr2()
|
||||||
|
codeChallenge = util.hashS256(codeVerifier)
|
||||||
args = dict(
|
args = dict(
|
||||||
client_id=self.params['client_id'],
|
client_id=self.params['client_id'],
|
||||||
response_type='code', # 'code id_token token',
|
response_type='code', # 'code id_token token',
|
||||||
state=state, nonce=nonce,
|
state=state, nonce=nonce,
|
||||||
scope=['openid', 'profile'],
|
code_challenge=codeChallenge, code_challenge_method='S256',
|
||||||
|
scope='openid profile email',
|
||||||
redirect_uri=self.params['callback_url'],
|
redirect_uri=self.params['callback_url'],
|
||||||
)
|
)
|
||||||
addArgs, codeVerifier = client.add_code_challenge()
|
#addArgs, codeVerifier = client.add_code_challenge()
|
||||||
print('***', addArgs, codeVerifier)
|
#print('***', addArgs, codeVerifier)
|
||||||
args.update(addArgs)
|
#args.update(addArgs)
|
||||||
self.storeSession(dict(state=state, nonce=nonce, code_verifier=codeVerifier))
|
self.storeSession(dict(state=state, nonce=nonce, code_verifier=codeVerifier))
|
||||||
authReq = client.construct_AuthorizationRequest(request_args=args)
|
loginUrl = '?'.join((self.params['auth_url'], urlencode(args)))
|
||||||
loginUrl = authReq.request(self.params['auth_url'])
|
#authReq = client.construct_AuthorizationRequest(request_args=args)
|
||||||
|
#loginUrl = authReq.request(self.params['auth_url'])
|
||||||
print('***', loginUrl)
|
print('***', loginUrl)
|
||||||
req.response.redirect(loginUrl, trusted=True)
|
req.response.redirect(loginUrl, trusted=True)
|
||||||
|
|
||||||
|
@ -109,6 +115,11 @@ class Authenticator(DummyFolder):
|
||||||
headers = dict(Authorization='Bearer ' + tdata['access_token'])
|
headers = dict(Authorization='Bearer ' + tdata['access_token'])
|
||||||
userInfo = requests.get(self.params['userinfo_url'], headers=headers)
|
userInfo = requests.get(self.params['userinfo_url'], headers=headers)
|
||||||
print('***', userInfo.json())
|
print('***', userInfo.json())
|
||||||
|
#self.storeSession(...)
|
||||||
|
#self.req.response.redirect(...)
|
||||||
|
|
||||||
|
def logout(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def storeSession(self, data):
|
def storeSession(self, data):
|
||||||
options = {}
|
options = {}
|
||||||
|
|
26
scopes/util.py
Normal file
26
scopes/util.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# scopes.util
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
from secrets import choice
|
||||||
|
import string
|
||||||
|
|
||||||
|
# random strings, hashes, encodings
|
||||||
|
# for authentication, encryption, and other purposes
|
||||||
|
|
||||||
|
BASE = string.ascii_letters + string.digits
|
||||||
|
BASE2 = BASE + '-._~'
|
||||||
|
|
||||||
|
def rndstr(size=16):
|
||||||
|
return ''.join([choice(BASE) for _ in range(size)])
|
||||||
|
|
||||||
|
def rndstr2(size=64):
|
||||||
|
return ''.join([choice(BASE2) for _ in range(size)])
|
||||||
|
|
||||||
|
def b64e(b):
|
||||||
|
return base64.urlsafe_b64encode(b).rstrip(b'=')
|
||||||
|
|
||||||
|
def hashS256(s):
|
||||||
|
h = hashlib.sha256(s.encode('ascii')).digest()
|
||||||
|
return b64e(h).decode('ascii')
|
||||||
|
|
Loading…
Add table
Reference in a new issue