Rationale
An ability to handle user authentication is very important part of every web framework. This functionality was missing for a long time in dashboard framework. Recently we implemented this missing part. Following paragraphs describe in detail how to include authentication support in dashboard projects.
Dependencies
User authentication support was implemented in dashboard-web ver. 0.11.0, so to use it in your project you should include following line in
requires
section of
setup.cfg
file:
dashboard-web >= 0.11.0
Actions.xml file markup
If you want to specify that some particular action requires authentication to be viewed and executed you should add to its definition
loginRequired="true"
attribute,
for example:
<action path="changeOneField" method="GET" type="dashboard.http.actions.siteview.ChangeOneFiled"
description="Modify selected parameter" app="ssb" loginRequired="true">
<output format="application/json" type="dashboard.http.views.GenericJSONView" />
</action>
For backwards compatibility actions without this attribute have
loginRequired="false"
by default.
Specifying authentication mechanism
Dashboard Action abstract class have
authenticate
method defined in a following way:
def authenticate(self, request):
raise AuthorizationException("You are not authorised to perform this request")
This means that authentication fails by default.
Dashboard controller check authentication only if action requires login:
# Check credentials
if actionMap.requiresLogin(actionID):
action.authenticate(self._request)
So in order to have some useful authentication mechanism a project has to provide one in a class derived from Action class. For example in siteview we have SiteViewAction class that is a parent of all siteview actions:
class SiteViewAction(Action):
'''
Parent for all the siteview actions
'''
...
def authenticate(self, request):
ctx = DAOContext.getDAOContext()
dao = DAOFactory.getDAOFactory().createSiteViewDAO(ctx)
access = dao.verifyCertificate(self.getUserName(request))
if not dao.verifyCertificate(self.getUserName(request)):
raise SiteViewAuthorizationException("You are not authorised to perform this request")
Please note that this action at failure throws different exception. This is to provide
customized authorization failures.
Handling authorization errors
By default authorization failure means throwing AuthorizationException.
The way this exception is handled is defined an siteview-web actions.xml file:
<exception module="dashboard.common.AuthorizationException">
<output format="text/plain" httpCode="401" type="dashboard.http.views.GenericExceptionTextView"/>
<output format="text/xml" httpCode="401" type="dashboard.http.views.GenericExceptionXMLView"/>
<output format="text/html" httpCode="401" type="dashboard.http.views.GenericExceptionTextView"/>
<output format="application/xhtml+xml" httpCode="401" type="dashboard.http.views.GenericExceptionTextView"/>
<output format="application/json" httpCode="401" type="dashboard.http.views.GenericJSONView"/>
</exception>
Customizing authentication errors
Default error handlers give you very basic view with some text in the of the screen. If you would like to provide your own handler for authentication failure, for example the view that will display nice jQuery window or something completely different you will have to do three things:
In the actions.xml file there is another important fragment:
<exception-set>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
href="/opt/dashboard/etc/dashboard-web/dashboard-actions_ssb.xml"
xpointer="xmlns(dashb=http://dashboard.cern.ch) xpointer(dashb:dashboard/dashb:exception-set/dashb:exception)" >
<xi:fallback/>
</xi:include>
...
This piece import exception handlers for particular project (ssb). You can add similar fragment for your own application.
Then in your application specific xml.file with actions definitions you can say something similar to this:
<exception-set>
<exception module="dashboard.http.views.siteview.SiteViewAuthorizationException">
<output httpCode="401" format="*/*" xsltDoc="xsl/siteview/AccessDenied.xsl" contentType="text/html" type="dashboard.http.views.siteview.SiteviewAuthorisationExceptionView"/>
<output httpCode="401" format="text/html" xsltDoc="xsl/siteview/AccessDenied.xsl" contentType="text/html" type="dashboard.http.views.siteview.SiteviewAuthorisationExceptionView"/>
<output httpCode="401" format="text/plain" xsltDoc="xsl/siteview/AccessDenied.xsl" contentType="text/html" type="dashboard.http.views.siteview.SiteviewAuthorisationExceptionView"/>
<output httpCode="401" format="text/xml" xsltDoc="xsl/siteview/AccessDenied.xsl" contentType="text/html" type="dashboard.http.views.siteview.SiteviewAuthorisationExceptionView"/>
<output format="application/json" httpCode="200" type="dashboard.http.views.GenericExceptionJSONView"/>
</exception>
</exception-set>
These are exception handler specific for
SSB. Now it you want to use them to handle authentication error in authenticate method for your base class just throw this specific exception.
Finally you should provide you own custom xsl template which will be render and displayed in case of failure.
--
MmNowotka - 17-Sep-2011