Friday, June 05, 2009

GWT and Spring Security - sample demo download

As requested, I have put together a sample app to demonstrate the GWT and Spring Security (formerly ACEGI) integration technique discussed in http://seewah.blogspot.com/2009/02/gwt-spring-integration-using.html and http://seewah.blogspot.com/2009/02/gwt-and-spring-security.html.

You can download the demo project here: http://www.fotowuj.com/gwt_spring_security_demo.zip

Essentially this app demonstrates how a GWT client can access a Spring-managed authentication service (via AuthenticationServiceServlet) to authenticate against Spring Security, and subsequently access a secured operation (getNumOfPrivatePublications) in another Spring-managed service (via DocumentServiceServlet). Please refer to the aforementioned blog articles for detailed discussion on how to integrate GWT and Spring Security.

You may also want to download a version of GWT.

NOTE THAT I HAVE ONLY TESTED THE DEMO WITH VERSION 1.5.3 OF GWT.

The zip contains a complete eclipse project consisting of:

1) source (both client and server)
2) all dependent jars
3) WebContent/WEB-INF/web.xml, which gets added to the final WAR
4) tomcat/webapps/ROOT/WEB-INF/web.xml, which is required to run in hosted mode
5) build.xml for running app in hosted mode (gwt-shell) and creating war (war)
6) .launch file for running app in hosted mode inside eclipse

You can run the demo in a number of ways:

1) WITH ECLIPSE - having imported the project into eclipse, right-click the .launch file inside eclipse and select "run as...", which will start the app in hosted mode. Note that you will probably have to change the gwt-dev-windows.jar location specified in the .launch file first.

2) RUNNING "gwt-shell" USING ANT - simply run "ant gwt-shell", which will start the app in hosted mode. Note that you will probably will have change the gwt-dev-windows.jar location specified in the build.xml file first.

3) RUNNING "war" USING ANT AND DEPLOYING IN TOMCAT - simply run "ant war", and deploy in Tomcat. Note that you will probably will have change the gwt-dev-windows.jar location specified in the build.xml file first.

Thanks

PS, a reader recently asked the question, "How come that you declare the services (DocumentService for example) both in the client and in the server package? Why not having the DocumentServiceImpl in the server package implement the DocumentService in the client package?"

And this is my anwser:

1) my design is based on the premises that the Spring layer and the GWT layer are very loosely-coupled e.g. in your company, you may already have all the Spring service beans already developed and you are just bolting a GWT frontend on top of this service layer. There are other reasons why you may want your GWT service interface to be slightly different from your Spring service interface as well.

2) The two interfaces ARE DIFFERENT! The GWT service interface getNumberOfPrivatePublications() method throws a checked ServiceSecurityException while the corresponding method in the Spring service interface does not. There may be alternatives that can potentially circumvent this, but to be honest, I have not really thought hard about this :-)

Anyway as I mentioned before, this is by no means the definitive way to integrate Spring Security in GWT. This method works great for me, but depending on your particular circumstances, this may not work so well. I am just hoping to give you guys some ideas :-)

18 comments:

cometta said...
This comment has been removed by the author.
cometta said...

i already became fan of your blog See Wah. Will you post gwt+spring+openId integration any sooner? if not, can you provide some brief guide how to do that? thank you

jmolins said...

Hi,
I have ported your code to GWT 1.6.4 and Google App Engine.
It works great after the necessary modifications.
If you want the code, please let me know.
Jose

Casey said...

jmolins - can you provide your source for the update to app engine? Thanks.

jmolins said...

Sure.
You can download from the following url:
http://www.megaupload.com/?d=QCWL1ZDN

yukoros said...

Hi,
Im a newbie to Acegi & GWT. How can this sample work with DaoAuthenticationProvider to use database user/roles data?

See Wah Cheng said...

Sorry work has been manic recently. Have not really been keeping an eye on the blog. Anyway the short answer to the last comment is it does not, since I am only using the method security feature in ACEGI / Spring Security in this case, and not really using the AuthentionProvider/Manager mechanism at all - I am doing my own authentication inside AuthenticationServiceImpl. But of course if you want to you can always implement your AuthenticationServiceImpl to PROGRAMMATICALLY use your AuthenticationProvider to authenticate (as opposed to using AuthenticationProvider DECLARATIVELY as you would normally with ACGI)

Anonymous said...

How come that you declare the services (DocumentService for example) both in the client and in the server package?

Why not having the DocumentServiceImpl in the server package implement the DocumentService in the client package

See Wah Cheng said...

two reasons really:

1) my design is based on the premises that the Spring layer and the GWT layer are very loosely-coupled e.g. in your company, you may already have all the Spring service beans already developed and you are just bolting a GWT frontend on top of this service layer. There are other reasons why you may want your GWT service interface to be slightly different from your Spring service interface as well.

2) The two interfaces ARE DIFFERENT! The GWT service interface getNumberOfPrivatePublications() method throws a checked ServiceSecurityException while the corresponding method in the Spring service interface does not. There may be alternatives that can potentially circumvent this, but to be honest, I have not really thought hard about this :-)

Anyway as I mentioned before, this is by no means the definitive way to integrate Spring Security in GWT. This method works great for me, but depending on your particular circumstances, this may not work so well. I am just hoping to give you guys some ideas :-)

The Pragmatic Researcher said...

see wah, thank you for this. jmolins thanks for the updated code to 1.6.4.

I do get one problem with the code however.
public interface AuthenticationServiceAsync {

public void authenticate(String username, String password, AsyncCallback lt; Boolean gt; callback);

public void logout(AsyncCallback lt; Object gt; callback);
}

I keep getting an error on the use of lt; Object gt; with AsyncCallback. The error is that "AsyncCallback parameterization is not compatible with the return type of AuthenticationService.logout".

How to fix this?

Thanks.

See Wah Cheng said...

Ah that is because since GWT 1.6 AsyncCallback<Object> is no longer compatible with methods which return void. You would have to change the AsyncCallback to AsyncCallback<Void> instead. Sorry I only developed and tested the code in version 1.5 of GWT.

And yes I was surprised to find that there is actually a "Void" class in Java!

The Pragmatic Researcher said...

Thanks See Wah!

There is another problem once I try to use this approach using my own service: I get a Error 500 due to a bizarre IllegalArgumentException thrown from the DependencyInjectionRemoteServlet.

I am not sure why this is happening the moment I add the @Secured("ROLE_ADMIN") on the method in my service.

Any Ideas? The service is simply getting a record from the database using hibernate.

The Pragmatic Researcher said...
This comment has been removed by the author.
The Pragmatic Researcher said...

See Wah, problem resolved. Interestingly enough, the state I was experiencing was the result of a minor typo in the DocumentServiceServlet when declaring the
@Autowired
com.mycompany.server.service.DocumentServiceImpl documentService;

instead of:

@Autowired
com.mycompany.server.service.DocumentService documentService;

Thanks again.

felipe said...
This comment has been removed by the author.
Thomas said...

Thanks See Wah!

I updated the demo with Spring 3.0.3, Spring Security 3.0.3 (they are separate now!) and GWT 2.1.0.M1. Download here: http://www.megaupload.com/?d=0H1Y9EBM

Pantsless said...

Hello! Can you plese re-upload your sample project, I really need it, and, as you know, MegaUpload is no more, unfortunately.

Anonymous said...

Would it be possible to have the sources uploaded somewhere ?

The matter discussed is truly interesting !

Thanks for all,

Cheers )