oidc auth: improvements, store info in cookie
This commit is contained in:
parent
0207d12b46
commit
c1f07effee
2 changed files with 64 additions and 24 deletions
|
@ -7,6 +7,7 @@ from scopes.server.app import zope_app_factory
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
server_port = getenv('SERVER_PORT', '8099')
|
server_port = getenv('SERVER_PORT', '8099')
|
||||||
|
base_url = getenv('BASE_URL', 'https://demo.cy7.de')
|
||||||
|
|
||||||
app_factory = zope_app_factory
|
app_factory = zope_app_factory
|
||||||
|
|
||||||
|
@ -19,8 +20,14 @@ dbpassword = getenv('DBPASSWORD', 'secret')
|
||||||
dbschema = getenv('DBSCHEMA', 'demo')
|
dbschema = getenv('DBSCHEMA', 'demo')
|
||||||
|
|
||||||
# authentication settings
|
# authentication settings
|
||||||
|
oidc_provider = 'https://a1.cy7.de'
|
||||||
|
oidc_client_id = getenv('OIDC_CLIENT_ID', '311613119816392525')
|
||||||
oidc_params = dict(
|
oidc_params = dict(
|
||||||
provider_url=getenv('OIDC_PROVIDER_URL', 'https://a1.cy7.de/oauth/v2/authorize'),
|
auth_url=getenv('OIDC_PROVIDER_URL', oidc_provider + '/oauth/v2/authorize'),
|
||||||
client_id=getenv('OIDC_CLIENT_ID', '311613119816392525'),
|
callback_url=getenv('OIDC_CALLBACK_URL', base_url + '/auth/callback'),
|
||||||
callback_url=getenv('OIDC_CALLBACK_URL', 'https://demo.cy7.de/auth/callback'),
|
client_id = oidc_client_id,
|
||||||
|
cookie_name=getenv('OIDC_COOKIE_NAME', 'oidc_' + oidc_client_id),
|
||||||
|
cookie_domain=getenv('OIDC_COOKIE_DOMAIN', 'cy7.de'),
|
||||||
|
cookie_lifetime=getenv('OIDC_COOKIE_LIFETIME', '86400'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# scopes.server.auth
|
# scopes.server.auth
|
||||||
|
|
||||||
from oic import oic, rndstr
|
from email.utils import formatdate
|
||||||
|
import json
|
||||||
|
from oic import oic, rndstr, unreserved
|
||||||
from oic.oic.message import AuthorizationResponse
|
from oic.oic.message import AuthorizationResponse
|
||||||
|
from time import time
|
||||||
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
|
||||||
|
@ -53,48 +55,79 @@ class Authenticator(DummyFolder):
|
||||||
|
|
||||||
prefix = 'auth'
|
prefix = 'auth'
|
||||||
|
|
||||||
|
def __init__(self, request):
|
||||||
|
self.request = request
|
||||||
|
self.params = config.oidc_params
|
||||||
|
|
||||||
def authenticate(request):
|
def authenticate(request):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def login(self, request):
|
def login(self):
|
||||||
params = config.oidc_params
|
req = self.request
|
||||||
print('*** login', self, request.getTraversalStack(), request['PATH_INFO'])
|
print('*** login', self, req.getTraversalStack(), req['PATH_INFO'])
|
||||||
#print('***', dir(request))
|
#print('***', dir(req))
|
||||||
client = oic.Client()
|
client = oic.Client()
|
||||||
#providerInfo = client.provider_config(params['provider_url'])
|
#providerInfo = client.provider_config(params['provider_url'])
|
||||||
#print('***', providerInfo)
|
#print('***', providerInfo)
|
||||||
#client.register(providerInfo['registration_endpoint'], application_type='web')
|
state = rndstr()
|
||||||
requestArgs = dict(
|
nonce = rndstr()
|
||||||
client_id=params['client_id'],
|
args = dict(
|
||||||
|
client_id=self.params['client_id'],
|
||||||
response_type='code', # 'code id_token token',
|
response_type='code', # 'code id_token token',
|
||||||
state=rndstr(), nonce=rndstr(),
|
state=state, nonce=nonce,
|
||||||
scope=['openid', 'profile'],
|
scope=['openid', 'profile'],
|
||||||
redirect_uri=params['callback_url'],
|
redirect_uri=self.params['callback_url'],
|
||||||
)
|
)
|
||||||
authReq = client.construct_AuthorizationRequest(request_args=requestArgs)
|
addArgs, codeVerifyer = client.add_code_challenge()
|
||||||
#loginUrl = authReq.request(client.authorization_endpoint)
|
args.update(addArgs)
|
||||||
loginUrl = authReq.request(params['provider_url'])
|
self.storeSession(dict(state=state, nonce=nonce, codeVerifyer=codeVerifyer))
|
||||||
|
authReq = client.construct_AuthorizationRequest(request_args=args)
|
||||||
|
loginUrl = authReq.request(self.params['auth_url'])
|
||||||
print('***', loginUrl)
|
print('***', loginUrl)
|
||||||
request.response.redirect(loginUrl, trusted=True)
|
req.response.redirect(loginUrl, trusted=True)
|
||||||
|
|
||||||
def callback(self, request):
|
def callback(self):
|
||||||
print('*** callback', self, request.form)
|
req = self.request
|
||||||
code = request.form['code']
|
print('*** callback', self, req.form)
|
||||||
|
data = self.loadSession()
|
||||||
|
code = req.form['code']
|
||||||
|
client = oic.Client()
|
||||||
|
print('***', data, code, client)
|
||||||
|
|
||||||
|
def storeSession(self, data):
|
||||||
|
options = {}
|
||||||
|
lifetime = int(self.params['cookie_lifetime'])
|
||||||
|
options['expires'] = formatdate(time() + lifetime, localtime=False, usegmt=True)
|
||||||
|
options['max-age'] = lifetime
|
||||||
|
domain = self.params['cookie_domain']
|
||||||
|
if domain:
|
||||||
|
options['domain'] = domain
|
||||||
|
#options['httponly'] = True
|
||||||
|
name = self.params['cookie_name']
|
||||||
|
value = json.dumps(data)
|
||||||
|
self.request.response.setCookie(name, value, **options)
|
||||||
|
|
||||||
|
def loadSession(self):
|
||||||
|
cookie = self.request.getCookies().get(self.params['cookie_name'])
|
||||||
|
if cookie is None:
|
||||||
|
raise ValueError('Missing authentication cookie')
|
||||||
|
data = json.loads(cookie)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
@register('auth', Root)
|
@register('auth', Root)
|
||||||
def authView(context, request):
|
def authView(context, request):
|
||||||
print('*** auth', context, request['PATH_INFO'])
|
print('*** auth', context, request['PATH_INFO'])
|
||||||
return Authenticator()
|
return Authenticator(request)
|
||||||
|
|
||||||
@register('login', Authenticator)
|
@register('login', Authenticator)
|
||||||
def login(context, request):
|
def login(context, request):
|
||||||
context.login(request)
|
context.login()
|
||||||
return DefaultView(context, request)
|
return DefaultView(context, request)
|
||||||
|
|
||||||
@register('callback', Authenticator)
|
@register('callback', Authenticator)
|
||||||
def callback(context, request):
|
def callback(context, request):
|
||||||
context.callback(request)
|
context.callback()
|
||||||
return DefaultView(context, request)
|
return DefaultView(context, request)
|
||||||
|
|
||||||
@register('logout', Authenticator)
|
@register('logout', Authenticator)
|
||||||
|
|
Loading…
Add table
Reference in a new issue