Raging Goblin

6 April 2013

Spring Roo 5: Role based views

Filed under: Java,Spring Roo — Raging Goblin @ 20:18
Tags: , ,

The user management functionality introduced in the previous post is not meant to be accessed by all users. This is the reason why we introduced the LogUserRole. Only members of the group ADMINSTRATOR should be able to add, update or delete users. To accomplish this we need 2 things:

  1. Check for the role the logged in user has when executing a method in the LogUserController.
  2. Remove the links to user management from the menus.

The first can be done by using the @PreAuthorize annotation. To enrich our application with this we first add this to webmvc-config.xml. Add the schema definition and enable the annotation by setting the head of this configuration file to:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:global-method-security pre-post-annotations="enabled "/>

Note that I added two things, the schema definition and the enabling of the pre-post-annotations.

Now, in the LogUserController we can add the @PreAuthorize annotation. E.g. the head of the method create will look like this:

@PreAuthorize("hasRole('ADMINISTRATOR')")
@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid LogUser logUser, BindingResult bindingResult, Model uiModel,
	HttpServletRequest httpServletRequest) {

You should do this for all the other methods as well.

We also add a AccessDeniedException configuration to the webmvc-config.xml to let the one who tries to access these methods know what went wrong:

<props>
  <prop key=".DataAccessException">dataAccessFailure</prop>
  <prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</prop>
  <prop key=".TypeMismatchException">resourceNotFound</prop>
  <prop key=".MissingServletRequestParameterException">resourceNotFound</prop>
  <prop key="org.springframework.security.access.AccessDeniedException">accessDenied</prop>
</props>

Add a view definition in src/main/webapp/WEB-INF/views/views.xml:

<definition extends="public" name="accessDenied">
  <put-attribute name="body" value="/WEB-INF/views/accessDeniedException.jspx"/>
</definition>

Create this view with a proper message in src/main/webapp/WEB-INF/views/accessDeniedException.jspx.

The second thing we need to do is change the menus so that a normal user will not access these methods accidentally. This can be done by adding a security tag to menu.jspx and surrounding the user management menu items with a role based security tag:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page"
	xmlns:menu="urn:jsptagdir:/WEB-INF/tags/menu"
	xmlns:security="http://www.springframework.org/security/tags" id="menu"
	version="2.0">

	<jsp:directive.page contentType="text/html;charset=UTF-8" />
	<jsp:output omit-xml-declaration="yes" />
	<menu:menu id="_menu" z="nZaf43BjUg1iM0v70HJVEsXDopc=">
		<menu:category id="c_logitem" z="SqQ1OSujMWnswClBZ0yGRL10ER0=">
			<menu:item id="i_logitem_new" messageCode="global_menu_new"
				url="/logitems?form" z="/iSFuRAPFJM3+CEo2pV5jdJJVfU=" />
			<menu:item id="i_logitem_list" messageCode="global_menu_list"
				url="/logitems?page=1&amp;size=${empty param.size ? 10 : param.size}"
				z="+VS0ebBCcdnV89xtkN9/QZZFFOw=" />
		</menu:category>
		<security:authorize ifAllGranted="ADMINISTRATOR">
		<menu:category id="c_loguser" z="Ya37W2Dk3lcEcn0gGjq3sCqfdxc=">
			<menu:item id="i_loguser_new" messageCode="global_menu_new"
				url="/logusers?form" z="YxH3QphXpDJh34UhJibtVutDlQw=" />
			<menu:item id="i_loguser_list" messageCode="global_menu_list"
				url="/logusers?page=1&amp;size=${empty param.size ? 10 : param.size}"
				z="De/VBRYqUuix4e1/Lcmen2eTqFY=" />
		</menu:category>
		</security:authorize>
	</menu:menu>
</div>

This will result in different views for different roles:

Admin menu

Admin menu


Menu user

User menu

Advertisements

Blog at WordPress.com.