[Twisted-web] Enforcing SSL for non-SSL requests

Marek Habersack grendel at caudium.net
Wed Aug 10 03:45:45 MDT 2005


On Wed, Aug 10, 2005 at 11:30:42AM +1000, Christopher Armstrong scribbled:
> On 8/10/05, Marek Habersack <grendel at caudium.net> wrote:
> > Hello everybody,
> > 
> >   I'm trying to find a way for a Nevow-based application to enforce SSL
> > connection on the client when they come in using insecure HTTP. Currently
> > when the client comes in using a http://site.com URL typed in the browser,
> > they will get no error and no response from the server as the connection is
> > closed. The application log reveals the following:
> 
> 
> 
> My application started out using twisted.web.util.ChildRedirector to
> the https URL for *all* plain http requests, but then we realised we
> needed some resources to be accessible over non-HTTPS (for various
> boring reasons) we wrote our own FancyRedirectory that looked a lot
> like ChildRedirector but made exceptions for certain paths in
> getChild.
That sounds simple and logical, but I'm having trouble fitting it in my
code, so forgive my ignorance, please, and bear with me while I ask a few more
stupid and obvious questions :). My application will use very few static
resources and all the virtual ones will be handled by a single class,
MainPage, which will call down to non-twisted/nevow code for specific urls
to handle requests. The entire application is guarded with
guard.SessionWrapper and requires the user to log in to access any and all
resources. Here is the code fragment that sets this up:

realm = SCRealm()
portl = portal.Portal(realm)
sCChecker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
sCChecker.addUser("test", "test")
portl.registerChecker(checkers.AllowAnonymousAccess(),credentials.IAnonymous)
portl.registerChecker(sCChecker)
root = guard.SessionWrapper(portl, "SC", useCookies=True)
application = service.Application("SC")

internet.SSLServer(8080,
                   appserver.NevowSite(root, logPath=config.web_log_path),
                   ServerContextFactory()).setServiceParent(application)

Very simple, but works well. Then the SCRealm class:

class SCRealm:
    implements(portal.IRealm)

    def prepareI18N(self, p):
        p.remember(I18NConfig(domain="sc",localeDir=config.localeDirectory), inevow.II18NConfig)
        return p
    
    def requestAvatar(self, avatarId, mind, *interfaces):
        for iface in interfaces:
            if iface is inevow.IResource:
                resc = None
                if avatarId is checkers.ANONYMOUS:
                    resc = self.prepareI18N(MainPage.MainPage())
                    logoutCallable = noLogout
                else:
                    resc = self.prepareI18N(MainPage.MainPage(avatarId))
                    logoutCallable = resc.logout
                if resc is not None:
                    resc.realm = self
                    
                return (inevow.IResource, resc, logoutCallable)
        raise NotImplementedError(_("Cannot support this interface"))

So, I suppose I could use the redirector class instead of MainPage.MainPage()
(or derive MainPage.MainPage from ChildRedirector) above, but it will still 
come after the internet.SSLServer attempts to handle the connection. What I'm 
not seeing is - how can I layout the setup code above so that I can put the 
redirector before the portal (I guess I could handle that inside the
requestAvatar method when avatarId is checkers.ANONYMOUS and do the redirect
there instead of presenting the login form) and how to handle the SSLServer's 
exception shown in the previous mail. A short code example on how to handle 
the exception would be greately appreciated ;)

I would love to avoid having to listen on two different ports to handle that, 
so the ideal thing to have would be a ConditionalSSLServer class which would start 
the SSL session if the client started the SSL handshake and would let the
programmer handle the situation when the incoming connection is a plain one.
How hard would it be to implement such a thing?

thanks a lot,

marek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://twistedmatrix.com/pipermail/twisted-web/attachments/20050810/91826bb8/attachment.bin


More information about the Twisted-web mailing list