Saturday, November 22, 2008

Leverage FlexSession to secure java based amf destination

Flex is gaining popularity in enterprise world. Authentication & authorization are common requirement of an enterprise application. To achieve this we often provide a login screen as the entry point to the application. Login screen validates user's credentials and based on role user will see various menu options and screens. 
Typical flex application consists of one or more swf file hosted on the net and remote service deployed as amf destinations. Using flex remoting application can talk to various backend systems based on ColdFusion, java etc. 
So where is the question of security. Flex app won't let you in unless you login to the application and flex app would let you perform only those operations available to your role.
Lets see how a java based remote object would look like. Before that lets consider this requirement
  • Two type of user: Read Only User & R/W user
  • Read-only user can see data on a screen
  • Read/Write user can read as well as update data on that screen
So, java backend class will have 3 main API exposed via remoting 
  • public User login(String username, String password) throws AuthException
  • public MyData getData() 
  • public void updateData(MyData data)
Login screen makes remote call to login() API to validate credentials and get users detail including roles. Based on role UI shows/hides the Update button to view/update data on post login screen.
Everything looks good but note that all the above 3 APIs are publicly exposed! Its very easy to forget about the fact that any remoting client, knowing the call details, will be able to invoke any of those exposed APIs. Thats where flex session would be useful to secure the APIs. Let see code snippet to get better picture.
public User login(String username, String password) throws AuthException
{
User user = myBusObj.login(username, password);
registerSession(user);
}
public MyData getData() throws AuthException
{
checkSession(reqRole);
return myBusObj.getData();
}
public void updateData(MyData data) throws AuthException
{
checkSession(reqRole);
return myBusObj.updateData(data);
}
private void registerSession(User user)
{
FlexContext.getFlexSession().setAttribute("AUTH_USER", user);
}
private void checkSession(String reqRole)
{
if(FlexContext.getFlexSession() == null || FlexContext.getFlexSession().getAttribute("AUTH_USER") == null || FlexContext.getFlexSession().getAttribute("AUTH_LEVEL") == null) throw new AuthException("some error message");
//check users role and compare with reqRole. if req role not present throw auth exception
}
With the above code in place, remote APIs can only called by authenticated & authorized clients. Find more detail on Flex Session here