Logo
Blog: Secure Flex UI with Django Backend

Django lends itself very nicely to serving custom Adobe Flex front end UI's.

There is one problem when implementing Flex on top of Django though, that being the need to secure Django views (aka Flex gateways). The normal Django authentication layer can prevent users from accessing secured content, but doesn't return it's result in a way that's easily captured and elegantly handled by Flex. Using normal Django authentication, you're Flex app will simply not work instead of catching the login issue and addressing it.

In order to elegantly handle security, we need to create a new custom authentication decorator for our Django back-end views and then add some Flex front-end code to catch our error and redirect to our Django login page. This example assumes that the login page "lives" outside of the Flex UI but could easily be modified to redirect to an internal Flex login interface.

This blog post provides a great example Flex UI on top of Django. Our example here will build on this structure.

First, lets add a custom Django decorator that will catch security errors and return an onStatus result through the PyAMF engine. This is simply implemented as:

 
def amf_login_required(f):
  def wrap(request, *args, **kwargs):
    if request.user.is_authenticated():
      return f(request, *args, **kwargs)
    else:
      raise pyamf.EncodeError('NotLoggedIn')
  wrap.__doc__=f.__doc__
  wrap.__name__=f.__name__
  return wrap
 

Once we have our decorator defined, call it on each of your secure View/Gateway functions just like the normal Django @login_required decorator.

 
@amf_login_required
def getContacts(request):
  return Contact.objects.all()
 

If a non-authenticated client access the getContacts view above, they will receive the following result:

 
<Response status="/onStatus">ErrorFault level=error code=u'EncodeError' description=u'NotLoggedIn'</Response>
 

Now we need to modify our Flex code to handle this properly. In the example structure, each Responder call provides a hook to the onFault function should the call return an error.

 
private function getContacts():void {
  connection.call("ContactService.getContacts",
  new Responder(onResult_contacts, onFault));
}
 

Now that Django is returning real AMF Error status all we need to do is modify the onFault code to catch our specific error and re-direct to a login page.

 
private function onFault(data:Object):void {
  if (data.code == 'EncodeError' && data.description == 'NotLoggedIn') {
    navigateToURL(new URLRequest('http://www.semi-legitimate.com/sls/login),'_self');
  }
  else{
    Alert.show('Uh oh... I just pooped.');
  }
}
Blog Index