Stephan Richter пишет:
On Sunday 28 January 2007 11:44, Alexei Ustyuzhaninov wrote:
This code is contained in the file mypackage/__init__.py, mypackage in
turn is loaded via ZCML.


This is bad form. You should have that code in another module.

Both plugins and PAU are registered successfully and I can access them with queryUtility. But the
authentication is carried through the standard mechanism and
MyAuthenticatorPlugin isn't even called.

There are a couple of things to be said here:

* Pluggable Authentication was not developed to work well globally. I know I had to tweak it a (tiny) bit to make it work for base registries.

* You should use the pluggable authentication utility from a site. You can do this via ZCML and baseregistries or adding it to the ZODB. You should look into configurator on how to do this programmatically.

Packages to check out:
z3c.baseregistry
z3c.configurator


I have looked a bit at the sources and make my own version of the publication class which (I think) makes the authentication to work as I want.

Here is my implementation:

overrides.zcml
--------------
<configure xmlns="http://namespaces.zope.org/zope";
           xmlns:browser="http://namespaces.zope.org/browser";>

  <publisher
      name="BROWSER"
      factory="mypackage.MyPublication.MyBrowserFactory"
      methods="GET POST HEAD"
      mimetypes="*"
      priority="10"
      />

</configure>


MyAuthentication.py
-------------------
from zope import interface
from zope.component import provideUtility
from zope.app.authentication import interfaces
from zope.app.authentication.interfaces import\
   ICredentialsPlugin, IAuthenticatorPlugin, IPrincipalInfo
from zope.app.authentication import PluggableAuthentication
from zope.app.authentication.httpplugins import HTTPBasicAuthCredentialsPlugin

class PrincipalInfo(object):
    interface.implements(interfaces.IPrincipalInfo)

    def __init__(self, id, title, description):
        self.id = id
        self.title = title
        self.description = description

class CascadeAuthenticatorPlugin(object):

    interface.implements(interfaces.IAuthenticatorPlugin)

    def authenticateCredentials(self, credentials):
        if credentials is None:
            return None
        params = my_authentication(credentials)
        if params is None
            return None
        else:
            return PrincipalInfo(*params)

provideUtility(HTTPBasicAuthCredentialsPlugin(), ICredentialsPlugin,\
   name='My Credentials Plugin')
provideUtility(CascadeAuthenticatorPlugin(), IAuthenticatorPlugin,
   name='My Authenticator Plugin')
pau=PluggableAuthentication('')
pau.credentialsPlugins=('My Credentials Plugin',)
pau.authenticatorPlugins=('My Authenticator Plugin',)

MyPublication.py
----------------
import transaction
from zope.app.publication.browser import BrowserPublication
from zope.app.publication.requestpublicationfactories import\
   BrowserFactory
from zope.app.security.principalregistry import\
   principalRegistry as prin_reg
from zope.security.management import newInteraction
from Authentication import pau

class MyPublication(BrowserPublication):

    def beforeTraversal(self, request):
        #p = prin_reg.authenticate(request)
        p = pau.authenticate(request)
        if p is None:
            p = prin_reg.unauthenticatedPrincipal()
            if p is None:
                raise Unauthorized # If there's no default principal
        request.setPrincipal(p)
        newInteraction(request)
        transaction.begin()

    def _maybePlacefullyAuthenticate(self, request, ob): ""

class MyBrowserFactory(BrowserFactory):
    def __call__(self):
        request_class, orig_publ=super(CascadeBrowserFactory,
           self).__call__()
        return request_class, MyPublication

I'm new to zope3, so could you estimate how well this approach corresponds to the zope architecture.

--
Alexei


_______________________________________________
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users

Reply via email to