Steve On Java - JavaFX

Hacking Java, JavaFX, and Flash with Agility
  • rss
  • Home
  • NightHacking Tour
    • [Archive] NightHacking Europe – The Road to Devoxx
  • SvJugFX
  • JFXtras
    • JFXtras Individual CLA
    • JFXtras Corporate CLA
  • 2013 Travel Map
    • Let’s Meetup!
    • 2012 Travel Map
  • Contact

JavaFX in Spring Day 3 – Authentication and Authorization

steveonjava | August 30, 2012

Welcome to Day 3 of the JavaFX in Spring blog series. In this post we are going to finish off the Customer Data application by taking advantage of the Spring Security APIs on the client.

It took a little bit of hacking, but I got a GitHub project put together with a straightforward JavaFX Maven build (details on this in a future post) to run everything. Please give the full project a view and run it from source so you can experiment with the application as you read this post:

Browse Project on GitHub

For easy reference, you can flip to any of the blogs here:

  • JavaFX in Spring Day 1 – Application Initialization
  • JavaFX in Spring Day 2 – Configuration and FXML
  • JavaFX in Spring Day 3 – Authentication and Authorization

Since my last post I made it out to two additional user groups in Texas, and had a great time speaking at both:

On the left is the Austin JUG, which is a large, well-established user group and on the right is the Houston JUG, which had a unique venue with personal monitors for all the attendees (this would be a great setup for a lab in the future!)  I posted the talks on Hacking JavaFX with Groovy, Clojure, Scala, and Visage and JavaFX 2 – A Java Developer’s Guide to SlideShare so they can grab the full presentation decks.

Getting back to the JavaFX in Spring example, in the last blog we covered Spring configuration of a JavaFX app to modularize the screens. As a simple example we did an error dialog to show how FXML ties in, but now let’s create a login page to demonstrate using Spring Security for Authentication.

The login dialog was created visually in SceneBuilder and the final version ended up looking like this:

(Since the first post I added in a few convenience hyperlinks for logging in as an employee or a manager)

And the controller code is as follows:

public class LoginController implements DialogController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private ScreensConfiguration screens;
    private AutowireFXMLDialog dialog;

    public void setDialog(AutowireFXMLDialog dialog) {
        this.dialog = dialog;
    }

    @FXML
    Label header;
    @FXML
    TextField username;
    @FXML
    TextField password;

    @FXML
    public void login() {
        Authentication authToken = new UsernamePasswordAuthenticationToken(username.getText(), password.getText());
        try {
            authToken = authenticationManager.authenticate(authToken);
            SecurityContextHolder.getContext().setAuthentication(authToken);
        } catch (AuthenticationException e) {
            header.setText("Login failure, please try again:");
            header.setTextFill(Color.DARKRED);
            return;
        }
        dialog.close();
        screens.showScreen(screens.customerDataScreen());
    }

    @FXML
    public void employee() {
        username.setText("employee");
        password.setText("lol");
    }

    @FXML
    public void manager() {
        username.setText("manager");
        password.setText("password");
    }
}

The important part for authentication is taken care of in the login method. This grabs the username and password from the respective fields and creates a new UsernamePasswordAuthenticationToken. To force authentication to take place immediately, we get autowire a reference to the Spring AuthenticationManager and call the authenticate method. If the user exists in our credential store the method will succeed, otherwise it will throw an AuthenticationError we catch in the enclosing try block.

For the purpose of this example we are using a local authentication store in the Spring XML config. You could easily hook up to an LDAP server or your chioce of authentication engines, but this makes the sample app we are building self contained. Here is the Spring config XML:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
             http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
    <security:global-method-security secured-annotations="enabled"/>
    <security:authentication-manager>
        <security:authentication-provider>
            <security:password-encoder hash="plaintext"/>
            <security:user-service>
                <security:user name="manager" password="password" authorities="ROLE_MANAGER"/>
                <security:user name="employee" password="lol" authorities="ROLE_EMPLOYEE"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

This sets up two different users and two roles. One is our manager who will have full access to the system and a laughably weak password, and the second is the employee who will only only have access to create new customers, but not delete. We are going to take advantage of these roles to secure the customer creation and deletion routines using annotation-based authorization.

Now that annotations-based configuration is setup, you can secure methods in your application by simply adding an appropriate annotation to it as shown in this code snippet from CustomerModel:

    @Secured("ROLE_MANAGER")
    public void remove(Customer customer) {
        restTemplate.delete("http://localhost:8080/crm/customer/" + customer.getId());
        customers.remove(customer);
    }

Any time this method is called, you will get an exception thrown that will prevent that method from getting executed and can be caught to give good user feedback, such as an error dialog:

To finish off the example, here is a screenshot of the completed example that includes a JavaFX Table for displaying elements that are pulled back from the server using the Spring RestTemplate API:

And again, you can find the full code available for download here:
Browse Project on GitHub

Now that I have shown you how you can take advantage of Spring in your JavaFX applications, it is only fair to point out some of the shortcomings you may encounter:

  • Jar Explosion – I tried to be minimalistic in my inclusion of dependencies, but still ended up with dozens of jar files for this example application. This may be an issue if you are deploying to resource constrained devices or over a thin network pipe, but for packaged applications should not be an issue.
  • All Permissions Required – Since Spring makes heavy use of aspect-oriented programming (AOP) libraries that manipulate bytecode, you won’t be able to run this application in the Java sandbox. The best approach is to request all permissions and code sign your application so the end user just gets prompted once.
  • AOP Glitches – In your own applications you will trip across various little quirks with AOP and bytecode manipulation that can make client programming quite hazardous. For example, if you put an @Secured annotation in a UI class file loaded in the main thread, you will get a ClassCastException on the proxy. It is possible to get the target class out like this, but it is nefarious enough that it bit me in a live-coding presentation.

Hopefully you have learned a little bit through this tour of JavaFX and Spring integration. I would love to hear what other folks have been doing to integrate these technologies in the comments section below.

 

Share this:

  • Twitter
  • Google +1
  • More
  • Facebook
  • LinkedIn
  • Email
Categories
JavaFX, Uncategorized
Tags
authentication, authorization, cglib, JavaFX, security, spring
Comments rss
Comments rss
Trackback
Trackback

« JavaFX in Spring Day 2 – Configuration and FXML NightHacking with James Gosling »

3 Responses to “JavaFX in Spring Day 3 – Authentication and Authorization”

  1. Ming Qin says:
    September 5, 2012 at 9:29 am

    Thank Steve’s example, I run this project successfully in both Netbeans and command lines .

    To run the project in Netbeans-see my blog -http://mingqin.wordpress.com/2012/09/05/72/

    To run Stephen project in dos command consoles. Below steps work for me.

    Open a command console

    cd server

    mvn jetty:run

    Open another command console

    cd client

    mvn compile

    mvn exec:java

    Reply
  2. Antonello says:
    September 13, 2012 at 11:23 am

    Thank you. This example, I was really helpful.

    I tried to create a similar application but my AuthenticationManager is always null.
    This is my AuthenticationManager:

    Surely I missed a few steps.
    Beans that I created work but the AuthenticationManager is always null.
    Could you sum up what steps are required to create a AuthenticationManager in JavaFX with spring security?
    my problem is very similar to this:
    http://stackoverflow.com/questions/11374904/spring-security-null-pointer-exception

    thanks
    Thanks

    Reply
  3. zonski says:
    October 26, 2012 at 7:28 pm

    Hey Steve,

    Just starting to read your blog. Good topic, and one close to my heart (a lot of overlap with my zenjava blog: http://www.zenjava.com/series/building-jee-applications-in-javafx-2-0/)

    I’m not so sure of your approach of having the AuthenticationManager on the client side? You are making REST calls to manipulate the data on the server side, so the security should be on the server side. Otherwise the URL’s can be hit directly and you have no security. You may find this post on it interesting: http://www.zenjava.com/2012/03/27/javafx-and-spring-security/

    In this, I use Spring RPC instead of REST+JSON but the logic would be exactly the same. Basically, secure the server side and then on the client side just do a ‘login’ request. This also removes any real Spring Security dependencies from your client code, massively reducing the JAR explosion. Give me a shout if you need more info.

    Additionally, you may want to look at this Maven plugin: https://github.com/zonski/javafx-maven-plugin

    This plugin is still pretty raw but should have a better outcome with less mucking around than your exec approach. The plugin wraps the offical JFX build tools and can build an executable JAR and native installers (MSI, deb, etc)

    The more people doing this sort of stuff the better. More focus on building real world apps might just mean a little more focus from the JFX team on this space.

    Reply

Leave a Reply

Click here to cancel reply.

  • Travel Map - Let's Meetup

Publications

  

Affiliations

Awards

2009/2011 JavaOne Rock Star!

Disclaimer

Views and opinions expressed here are all my fault... complain to me, not my employer. :)
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox
loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.