provide Unauthorized handler, example use in inst/loops via overrides.zcml

This commit is contained in:
Helmut Merz 2026-05-04 07:23:41 +02:00
parent 3a5b33f529
commit d7b1eb6257
3 changed files with 47 additions and 5 deletions

View file

@ -24,6 +24,9 @@ dbpassword = getenv('DBPASSWORD', 'secret')
dbschema = getenv('DBSCHEMA', 'demo') dbschema = getenv('DBSCHEMA', 'demo')
# OpenID Connect (OIDC, e.g. via zitadel) authentication settings # OpenID Connect (OIDC, e.g. via zitadel) authentication settings
authentication_method = 'cookie' # 'legacy'|'select'|'oidc'|'cookie'
# OpenID Connect (OIDC) authentication settings
oidc_provider = getenv('OIDC_PROVIDER', '') #'https://instance1-abcdef.zitadel.cloud') oidc_provider = getenv('OIDC_PROVIDER', '') #'https://instance1-abcdef.zitadel.cloud')
oidc_client_id = getenv('OIDC_CLIENT_ID', '12345') oidc_client_id = getenv('OIDC_CLIENT_ID', '12345')
oidc_params = dict( oidc_params = dict(

View file

@ -1,4 +1,27 @@
<configure xmlns="http://namespaces.zope.org/zope"> <configure xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<browser:page
for="zope.security.interfaces.IUnauthorized"
name="index.html"
class="loops.server.auth.Unauthorized"
permission="zope.Public" />
<!--<browser:page
for="zope.publisher.interfaces.INotFound"
name="index.html"
class="loops.browser.common.NotFound"
permission="zope.Public" />
<browser:page
for="zope.interface.common.interfaces.IException"
name="index.html"
class="loops.browser.common.SystemErrorView"
permission="zope.Public" />-->
<!--<browser:defaultSkin name="Loops" />-->
<include package="loops.server" file="loginform.zcml" />
</configure> </configure>

View file

@ -4,8 +4,9 @@
# and other authentication and authorization stuff. # and other authentication and authorization stuff.
from scopes.web.auth import oidc from scopes.web.auth import oidc
from zope.authentication.interfaces import IAuthentication from zope.authentication.interfaces import IAuthentication, IUnauthenticatedPrincipal
from zope.browserpage import ViewPageTemplateFile from zope.browserpage import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from zope.component import provideAdapter, getUtility, provideUtility from zope.component import provideAdapter, getUtility, provideUtility
from zope.interface import implementer, Interface from zope.interface import implementer, Interface
from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserPage from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserPage
@ -14,6 +15,9 @@ from zope.security.proxy import removeSecurityProxy
import config import config
from logging import getLogger
logger = getLogger("loops.server.auth")
def registerAuthUtility(config): def registerAuthUtility(config):
baseAuth = getUtility(IAuthentication) baseAuth = getUtility(IAuthentication)
print('*** registerAuthUtility, baseAuth:', baseAuth) print('*** registerAuthUtility, baseAuth:', baseAuth)
@ -38,6 +42,10 @@ class LoginPage:
return self.authOidc() return self.authOidc()
return self.index() return self.index()
@Lazy
def isAnonymous(self):
return IUnauthenticatedPrincipal.providedBy(self.request.principal)
def authOidc(self): def authOidc(self):
oidc.Authenticator(self.request).login() oidc.Authenticator(self.request).login()
return '' return ''
@ -57,9 +65,17 @@ class LoginPageSelect(LoginPage):
class Unauthorized(LoginPage): class Unauthorized(LoginPage):
def __call__(self): def __call__(self):
print(f'*** unauthorized: user = {self.request.principal.id}, authMethod = {self.authMethod}') response = self.request.response
return "Unauthorized" # make sure that squid does not keep the response in the cache
#return super(Unauthorized, self).__call__() response.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT')
response.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate')
response.setHeader('Pragma', 'no-cache')
logger.warn(f'unauthorized: user={self.request.principal.id}, authMethod={self.authMethod}')
if self.isAnonymous:
return super(Unauthorized, self).__call__() # open or redirect to login page
else:
response.setStatus(403)
return 'Unauthorized'
def getConfigAuthMethod(): def getConfigAuthMethod():