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 :-)
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 :-)
Comments
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
You can download from the following url:
http://www.megaupload.com/?d=QCWL1ZDN
Im a newbie to Acegi & GWT. How can this sample work with DaoAuthenticationProvider to use database user/roles data?
Why not having the DocumentServiceImpl in the server package implement the DocumentService in the client package
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 :-)
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.
And yes I was surprised to find that there is actually a "Void" class in Java!
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.
@Autowired
com.mycompany.server.service.DocumentServiceImpl documentService;
instead of:
@Autowired
com.mycompany.server.service.DocumentService documentService;
Thanks again.
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
The matter discussed is truly interesting !
Thanks for all,
Cheers )