Java, JavaFX, Groovy, Grails …
Archive for May, 2010
Jersey JAX-RS, Tomcat, Basic Auth and Security Annotations
May 21st
While doing some research on securing JAX-RS Restful services, I came across this question on stackoverflow which asks how best to wire up a simple security mechanism for:
- Jersey JAX-RS.
- Tomcat.
- Basic Authentication.
- JSR 250 Annotations such as @RolesAllowed.
So in a nutshell….this can be accomplished quite easily by configuring the following:
- tomcat-users.xml (found in the conf dir of your tomcat install).
- the applications web.xml.
- and lastly annotating the restful service.
By adjusting the tomcat-users.xml you will create a tomcat memory realm of usernames and passwords.
To do this…simpy add the following to the tomcat-users.xml file:
<role rolename="admin" /> <user username="admin" password="adminadmin" roles="manager,admin,user" /> <role rolename="user" /> <user username="user" password="useruser" roles="user" />
<servlet> <servlet-name>ServletAdaptor</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>com.sun.jersey.spi.container.ResourceFilters</param-name> <param-value>com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ServletAdaptor</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Secure</web-resource-name> <url-pattern>/resources/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> <role-name>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>Test</realm-name> </login-config> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role>
import com.sun.jersey.core.util.Base64;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
@Path("/Test")
@RolesAllowed("admin")
public class Test {
@GET
@Produces("text/plain")
@RolesAllowed("user")
public String getNumber(@Context HttpHeaders headers){
System.out.println( getCredentials(headers));
return "1 Secured with User";
}
@GET
@Path("/Secure")
@RolesAllowed("admin")
@Produces("text/plain")
public String getSecureNumber(@Context HttpHeaders headers){
System.out.println( getCredentials(headers));
return "2 Secured with Admin";
}
private String getCredentials(HttpHeaders headers) {
String auth = headers.getRequestHeader("authorization").get(0);
auth = auth.substring("Basic ".length());
String[] values = new String(Base64.base64Decode(auth)).split(":");
String username = values[0];
String password = values[1];
String return_val = "Username = " + username + " Password = "+ password;
return return_val;
}
}If you deploy to localhost with the above configuration the urls are as follows
- an “admin” person has access to http://localhost:8080/MyService2/resources/Test/Secure
- a “user” person has access to = http://localhost:8080/MyService2/resources/Test/
Because this is “BASIC” security…a pop up will appear to log the person in when a request is made to the secured resource.
You can find a zipped copy of my Netbeans project here
New Grails Spring Security Core Plugin
May 8th
Not to be confused with my prior post based on the Acegi plugin…the Spring/Grails folks (more specifically Burt Beckwith) has released a new Spring Security Core Plugin. As per the docs, the plugin greatly simplifies the work of getting Spring Security 3 to work within grails….and I for one very much agree.
Similar to my last post where I used the Acegi plugin, I will list the actions one must take to get a trivial grails based app going with the new spring security core plugin. These steps are very much right from the docs with only a few exceptions
- HTTPS Channel Security(similar to my last post) support will be added.
- Netbeans IDE will be used instead of the command line. (as much as possible)
Let’s get started:
- Set up grails within Netbeans and create a new project as described in my initial post.
- Download the new Spring Security Core Plugin as it is currently not in the default plugin list.
- Manually install the plugin using the Netbeans interface by right clicking the project and selecting the “Grails Plugins…” command then click on the “New Plugins” tab as shown below.

- Once you have provided the plugin path…press the “Install”
- Next you will want to run the “s2-quickstart” command with “User” and “Role” as parameters. I was unable to get Netbeans to properly run this command so I resorted to using the command line.

- The script creates the “User”,”Role” and “UserRole” domain classes as well as the required controllers.
- As per the tutorial, create a controller that must be secured for testing purposes by running the “create-controller” command and “Secured” as the name parameter.

- Modify the controller to render some output and secure it to the Role of “Admin”.
package springsecuritycore import grails.plugins.springsecurity.Secured class SecuredController { @Secured(['ROLE_ADMIN']) def index = { render 'Secure access only' } } - Modify the Bootstrap.groovy file to add a default user.
import com.test.Role import com.test.User import com.test.UserRole class BootStrap { def springSecurityService def init = { servletContext -> def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true) def userRole = new Role(authority: 'ROLE_USER').save(flush: true) String password = springSecurityService.encodePassword('password') def testUser = new User(username: 'me', enabled: true, password: password) testUser.save(flush: true) UserRole.create testUser, adminRole, true assert User.count() == 1 assert Role.count() == 2 assert UserRole.count() == 1 } } - At this point if you run the application and attempt to access the “SecuredController” you will prompted by the default login page for the username=”me” and password=”password”. This was configured in the Bootstrap.groovy file.
- To configure Channel Security for HTTPS support you will add the following code to your Config.groovy file
grails.plugins.springsecurity.secureChannel.definition = [ '/login/**': 'REQUIRES_SECURE_CHANNEL' ]
- Now run the command with “run-app” command with the “-https” flag you will find https channel security is configured to run on the “login” url.

- That is pretty much everything…. and please keep in mind that if you are using the postgres database … the domain class “User” will conflict with postgres (which has a table defined as “User) and must be mapped to a different table (see this post and response by Burt Beckwith on the grails forum).
- Hope this was helpful to someone and many thanks to the grails community and the plugin creator.
Project code is found on Github here.