Neosavvy, Inc Modern Knowledge Blog

9Nov/092

Building a Simple Login Mechanism with Flex, Spring-Flex, and Spring-Security

Introduction

This guide is a step by step architecture walkthrough of a simple Flex application I have constructed to help depict how to build a Flex application with BlazeDS/Java/Hibernate and an in memory database. The attempt will be to use the newest features of Spring to integrate security and BlazeDS integrations since they are relatively new and undocumented at this point.

You can find the code at the time of this writing tagged here: http://www.neosavvy.com/svn/neosavvy/projects/commons-user/tags/initial-integration-of-user-registration-with-blazeds/

Please note that all SVN Links are temporarily locked down - I apologize for the inconvenience but please find the source here: http://www.neosavvy.com/commons-user-blog-post.tar.gz

The following requirements are attempted to be met with this project:

  1. Provide a Registration dialog that allows new users to supply Username, Name, Email, and password information
  2. Provide a login dialog that allows a user to authenticate
  3. Provide a basic user management system that can be used by administrative users and will serve as the user management system for other applications
  4. Provide a secured UI and a non-secured UI
    - Non Secured features are Login / Registration screens
    - Secured features are User Management screens (Some admin – some all users)

Now that the rudimentary requirements are out of the way I will explain how the application was specified. I used the application Balsamiq Mockups to design the login and registration screens and they should accurately depict what was attempted to be built.

Simple Design / Wireframes

This first screen that a new user will be prompted to click a button to initialize the user registration process.

Once the new user has clicked the new user button the next screen will be rendered to prompt for necessary input to create a user. This is standard user information and could be extended depending on the scenario needing it.

This screen shows a few simple validation errors that will be integrated to ensure valid user creation.

After a user successfully registers a simple confirmation will be displayed and the users account will be active. For the intent of simplicity no confirmation is required in the code to authorize email addresses or integrate captcha at this time. A similar screen to the one below will be implemented for server side errors when creating a user such as uniqueness constraint violations on user creation.

If you would like to open the BMML files or the PNGs they are checked in here:

http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/doc

They were created with Balsamiq Mockups http://www.balsamiq.com/products/mockups which is a great inexpensive way to create simple mockups of screens before you spend hours trying to make them work.

Architecture

The chosen architecture for this application is going to be my standard architecture for applications produced by Neosavvy for Open Source initiatives. The following technologies are used

  1. Maven – Build and Configuration Management
  2. Nexus – Dependency management Repository
  3. HSQLDB – In Memory RDBMS
  4. JUnit 4 – Unit / Integration Testing for Java
  5. Java 1.5 (I know it is EOL but this ensures maximum support in the Field at this time as I know of multiple production apps that have not and can not upgrade to 1.6)
  6. Tomcat 5.5 for Maven based deployment testing via Cargo Maven plugin
  7. Spring 2.5.6 – At the time of writing this is the minimum version to support Spring’s Flex Libraries
  8. Spring Flex 1.0.1.RELEASE
  9. Hibernate 3.0.GA
  10. Flex 4.0.0 – At the time of this writing Flex 4 is in Beta and the Sparc packages are in Flux. The 4.0 version of the Flex SDK is used to build but the MX packages are used for the interface. A conversion to the Sparc packages will occur in a later post to help understand what that entails

The application is organized into separate projects as Maven projects and has the following structure

I have made an attempt to show the dependencies of the projects to depict the build order when maven executes. The top level project is not depicted but the project structure can also be seen by opening the top level pom in IntelliJ.

The intent of each of these project is my standard approach to developing a RIA and is as follows:

Commons-user-java-lib
- All of the Unit / Integration testing lives in this project for Java
- All of the Spring configuration specific to wiring the JAR together lives here
- All of the Value Objects, Service Architecture, and DAOs are defined in this project

Commons-user-flex-model-lib

- This project encapsulates generated DTOs for the frontend consumption
- Autogeneration is accomplished via Flex Mojo’s generator plugin

Commons-user-config

- To configure a BlazeDS application some files are required and can be shared with the flex client and the webapplication configuration
- Extracting them into a separate project allows for the Flex code and Java code to share the configuration rather than duplicate it

Commons-user-webapp

- This project outputs a WAR and assembles the Flex and Java code into a working web application
- Theoretically Java Integration tests more appropriately belong here, but there are some problems making eclipse easily build/test/code/repeat so they were moved to the Jar. IntelliJ handles this fine, but Eclipse is the defacto standard so I moved them.

Commons-user-top-level (not depicted in above diagram)

- This project is the top level project and assembles the modules via multi-module configuration in Maven.
- This also manages dependencies across projects to maintain a uniform set of dependencies
- Properties to share amongst projects are also declared at this level
- Project information related to developers and documentation are also at this level

Java Implementation

Now that the overall architecture is explained let’s explain how the Java implementation was accomplished. I attempted to use a test driven development approach and also leveraged Spring’s test architecture to load Application Context and set database state (by deleting existing values in a transaction).

Test Classes

BaseSpringAwareTestCase ( http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/commons-user-java-lib/src/test/java/com/neosavvy/user/BaseSpringAwareTestCase.java )

This is a good place to start because this class will load your application context for you and allow you to extend it and write good test cases. It’s UML structure is depicted below:

The important part to notice is that it extends from AbstractTransactionalJUnit4SpringContextTests, verything else if for free.

The next class of note is the test suite that verifies all the functionality that is being attempted in this feature.

Click here to see full size diagram

Click here to see full size diagram

As you can see all of the test cases that support the basic registration functionality and login functionality are stubbed in and at the time of writing have been completely fleshed and and work. (see http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/commons-user-java-lib/src/test/java/com/neosavvy/user/TestUserDAO.java )

Model Classes

The next step usually for me is to define the model classes as can be seen in the diagram below. Source here: http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/commons-user-java-lib/src/main/java/com/neosavvy/user/dto/UserDTO.java

Click here to see full size image

Click here to see full size image

DAO Interface

The next step is to define some basic DAO interface operations. The following were implemented to support the features depicted in the requirements. At this point you will notice none of these will support “login” as this will be a feature of implementing Spring Security later. Source is here: http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/commons-user-java-lib/src/main/java/com/neosavvy/user/dao/UserDAO.java

Click here to see full size diagram

Click here to see full size diagram

DAO Interface Implementation

Now it is time to write some actual working code. This is done by implementing the DAO interface. Usually it is best to wire the interface’s implementation to your test case before actually coding the functionality. For brevity I will just show the full working class, but you can assume I wrote it that way. It is worth noting that the Implementing class extends HibernateDaoSupport and implements UserDAO. This helps with wiring Spring to datasources and provides transaction support out of the box so you don’t have to think about it.

Click here to see full size image

Click here to see full size image

Spring Configuration

After all this is complete it is time to wire all this together with Spring. This can be done with the applicationContext.xml and some extras are thrown in for JOTM transaction management for deployment to containers like Tomcat that do not have a PlatformTransactionManager. Here is a diagram that depicts the beans that are configured.

Click here to see full size diagram

Click here to see full size diagram

At this point the Jar definition is complete. The test case runs to completion with no errors and the HSQLDB starts up when Maven executes. The HSQLDB configuration uses an in memory configuration to allow the startup sequence to always have a predictable state.

Configuring the Spring services via BlazeDS / Spring-Flex

Note that this is a great step by step guide to follow: http://static.springsource.org/spring-flex/docs/1.0.x/reference/html/ch01.html

In the commons-user-webapp there is some configuration to Spring that exposes all of the services via BlazeDS.

To start make sure that you are using DispatcherServlet to configure Spring instead of ContextLoaderListener.

Notice the following from the web.xml (http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/commons-user-webapp/src/main/webapp/WEB-INF/web.xml

<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext.xml
classpath:flexContext.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
 
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

Notice that the flexContext.xml is included without the *. The reason for this is because the * tells Spring to load a resource from any dependent Jar file. The applicationContext.xml lives in commons-user.jar so it has to use the * operator, while the flexContext.xml is in the WEB-INF/classes directory.

About the flexContext.xml file:

All that had to be done to expose the UserService was to point the flexContext.xml at this bean with the following configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flex="http://www.springframework.org/schema/flex"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">
 
<flex:message-broker>
<flex:remoting-service default-channels="user-amf" />
</flex:message-broker>
 
<flex:remoting-destination ref="userService" />
 
</beans>

It is also required that you ensure you have the services-config.xml defined in the commons-user-config project. Take a look at the following file: http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/commons-user-config/src/main/resources/services-config.xml

The most important part to ensure that you include is:

<?xml version="1.0" encoding="UTF-8"?>
<services-config>
 
<channels>
<channel-definition id="user-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
<polling-enabled>false</polling-enabled>
</properties>
</channel-definition>
</channels>
</services-config>

At this point all that is required to test and ensure that the BlazeDS integration is complete.

Flex Implementation

The next step is to get those model objects proxied on the Flex side as actionscript. I leveraged Marvin Froeder’s Flex Mojo’s plugin that hooks into the GAS3 groovy based actionscript generation tools. This generates all the classes specified in the POM file for maven and places a Base class in the target/generated-classes/flex directory before compiling a SWC. All the extended versions of the classes end up in src/main/flex/com/neosavvy/dto/ and allow a developer to put custom logic there.

Take a look at the following to understand how code generation works:

<build>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>${flex.mojos.maven.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<includeJavaClasses>
<includeClass>com.neosavvy.user.dto.*</includeClass>
</includeJavaClasses>
<beanTemplate>
<template>${basedir}/src/main/template/beanBase.gsp</template>
<template>${basedir}/src/main/template/bean.gsp
</template>
</beanTemplate>
</configuration>
</execution>
</executions>
<configuration>
<configurationReport>true</configurationReport>
<debug>true</debug>
<locales>
<param>en_US</param>
</locales>
<targetPlayer>10.0.0</targetPlayer>
</configuration>
</plugin>
</plugins>
</build>

It is also necessary to add a dependency to the Jar project as a provided scope to allow the generator plugin to find the Java classes it is supposed to generate.

<dependency>
<groupId>com.neosavvy.commons.user</groupId>
<artifactId>commons-user-java-lib</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>

Executing the maven build on this project will cause the classes to get regenerated.

Now in the interest of not using complicated frameworks but focusing on the integration points of Flex I have used some not-so-best practices when developing the Flex client. There are frequent examples of RemoteObjects defined in the mx:Script section of some of these components. I plan to use this as a starting point for new Flex developers as it is likely that they would attempt to develop in this way if they are just starting out.

The RegistrationAndLoginWindow.mxml is the top level MXML document that handles transitioning between the error screens and the registration screens. The actual code to implement the service calls is in the UserRegistration.mxml file. The two error handling files are UserFailed.mxml and UserConfirmed.mxml. The NewUserRegistration.mxml is what starts the registration process.

To see those classes take a look at the source here: http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/commons-user-flex-client/src/main/flex/com/neosavvy/user/registration/

Testing and Verification

Now that the Flex Client is defined you can test to see if the code is working. To explore my example follow the instructions below. Hopefully the guide above and the code samples will be enough to help you get going with a similar setup.

  1. Place the settings.xml from my SVN location into your ~/.m2/ directory from here: http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/settings.xml
  2. Checkout the source code with the following command:
    svn co http://www.neosavvy.com/svn/neosavvy/projects/commons-user/trunk/ commons-user
  3. Change directory into your commons-user directory and run a maven clean install
    mvn clean install
  4. Wait until the code compiles and test cases complete. The build should be successful.
  5. Change directories into the commons-user-webapp and start the application served
    cd commons-user-webapp ; mvn cargo:start
  6. The server should start then you can open your browser and navigate to http://localhost:8080/commons-user-webapp/
  7. Click the button at the top of the Application
  8. Notice that you can being the registration flow and create a user
  9. After completing the registration you should notice that your user has been added to the grid.
Click here to see full image

Click here to see full image

This concludes the simple BlazeDS integration with Spring Flex. In a future post I will explore the hooks into Spring Security for Spring Flex. Also will explore the restriction of some of the administrative features such as deleting a user and viewing/searching users.

Thanks for reading! Please email me at aparrish@neosavvy.com if you have any questions. Also please feel free to comment on this post and ask questions.

If you are interested in seeing part two of this post please click here

Comments (2) Trackbacks (0)
  1. Hi,

    Nice article, but I really need to see the code to truly “understand”, however, when I hit the URL listed it asks for password info. Can you supply or open up access? Thanks a ton.

    Joe

  2. Joe:

    I have posted the artifacts here and unfortunately had to secure my repository.

    http://www.neosavvy.com/commons-user-blog-post.tar.gz

    Please feel free to download all the source from the URL above and let me know if you have any questions compiling it or using it.

    Cheers,
    Adam


Leave a comment


No trackbacks yet.

Pages

Categories

Blogroll

Archive

Meta