Plone secure login, the secure part
After showing the insecure defaults, now how to fix it.
In Plone secure login, the insecure part I showed the insecure login via http and the insecure authentication cookie. Here's a way in which you can improve the security.
Secure sessions
If you install SessionCrumbler according to the installation instructions (basically replacing cookie_crumbler with session_crumbler), the login mechanism will use a cookie with a session ID instead of a cookie with the login data. Using LiveHttpHeaders:
Cookie: _ZopeId="58768270A2TfqKoWLsw"
This is one less thing to worry about. It comes at the price of some disadvantages, see plip 48 :
- In the standard setup, sessions apparently only allow 1000
users. And every session takes up some memory, so if your site has
lots of logged in users, you can get a performance hit.
You can solve the 1000-user-limitation with a config setting, though of course not the memory hit, in your zope.conf:
maximum-number-of-session-objects 10000 - With a multiple-zeo-setup you need to look at http://www.zopelabs.com/cookbook/1061234337
To remove the cookie_authentication and replace it with a session_authentication, you can use the following code in your installer:
# Add this as a method in your (App)Install.py
if 'cookie_authentication' in portal.objectIds():
portal.manage_delObjects(ids=['cookie_authentication'])
out.write("Cookie auth found, removed it.\n")
SCfactory = portal.manage_addProduct['SessionCrumbler'].manage_addSC
SCfactory('session_authentication')
After you've done that, you now suddenly have a problem with your
plone logins. It turns out that
CMFPlone/skins/plone_login/login_form.cpt and
CMFPlone/skins/plone_portlets/portlet_login.pt have a hardcoded
line in there that checks for cookie_authentication:
auth nocall:here/cookie_authentication|nothing
You'll have to change that to session_authentication in both places.
Secure https
When you use https instead of http, you encrypt all your traffic. Cookies, form parameters, the page itself, all. The drawback is that https is not cached, which is a good way of killing the performance of your site :-)
You can get away with doing the minimum: just use https for sending
the login data. The came_from parameter that plone passes along in
the login form 'll put you right back in normal http country
afterwards, so that's OK.
So you need to change the login portlet and the login_form to have https as their action instead of just http. The login mechanism should redirect back to the http site afterwards. But you probably only want this on the production site, not on the development machines. It can get more complicated: say that you have both a production and a preview site, then you'd need to take care of not accidentally redirecting from preview to production or the other way around.
Pair programming with Daniel Nouri, I created a getLoginAction.py
script that would return the normal "portal url + /login_form"
action for sending the login data, except when the URL starts with a
specific string that you use to identify your
partially-https-fronted production website:
## Script (Python) "getLoginAction"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=
##title=return the action for logging in, taking into account https
portal_url = context.portal_url()
NEEDS_HTTPS = ['http://your.production.website.nl/',
]
for url_start in NEEDS_HTTPS:
if portal_url.startswith(url_start):
portal_url = portal_url.replace('http://', 'https://')
return portal_url + '/login_form'
You need to call this script from both the login_form and the portlet_login. The following example is from the login_form.cpt:
<form tal:attributes="action context/getLoginAction"
method="post"
id="login_form"
tal:condition="python:auth">
Now the only thing left to do is to make sure your webserver accepts
https connections, at least to /login_form.


Session auth & PlonePAS
How do you get session authentication working with PlonePAS?