Clone wiki

grails-activiti-shiro-security-plugin / home_en


This plugin integrates Activiti with Shiro Security in an application Grails. It is based on the work of Lim Chee Kin (plugins for Activiti and Spring Security) and Peter Ledbrook (plugin Shiro). Is licensed under the Apache Software License v2.0.


Domain Models

Activiti uses a security model with three entities (User, Role, and the link between the two), for it defines two interfaces that must be implemented by domain models User and Group, the third is the association m: n between them (UserRole).

The following model is a slight adaptation of the domain model based Spring Security:

Not all class attributes are necessary (for fishing only defined interfaces and ShiroUser Activiti passwordChangeRequiredOnNextLogon). These classes can be created from shiro plugin for grails.

The plugin uses conventions to generate dynamic queries permit therefore is neceserio UserRole in the user attribute names and role names conincidan with User and Role classes used in this case and ShiroRole ShiroUser.

Activiti need to query based on the user name and group ID for this attribute id models a String and must be mapped as follows:

For User

static mapping = {
		password column: '`password`'
		id generator: 'uuid'

For Group

static mapping = {
                id generator: 'assigned'

To UserRole

static mapping = {
		id composite: ['shiroRole', 'shiroUser']
		version false

Implying that identifiers should be assigned roles, these identifiers must contain the names of the roles used in selection expressions psoibles users during the definition process tasks, the following excerpt is taken from VacationRequest process:

<userTask id="initiateVacationRequest" activiti:formKey="/vacationRequest/create"
			name="Initiate Vacation Request">
			<documentation>Vacation request by ${username}</documentation>
		<sequenceFlow id="flow1" targetRef="handleVacationRequest"
			sourceRef="initiateVacationRequest" />
		<userTask id="handleVacationRequest" activiti:formKey="/vacationRequest/approval"
			name="Handle Vacation Request">
			<documentation>Vacation request by ${username}</documentation>

because the Activiti performs the search for potential users based on their formal expressions (formalExpression) the process xml.


The plugin implements the interfaces GroupManager and of Activiti and configures the IdentityService to use implementations, using properties Config.groovy (See installation) to generate dynamic queries.

Must be registered in the user session the user name to look Activiti groups and potential users to the tasks for this plugin implements the method attachUsername2Session() ShiroActivitiSessionService, this service must be injected into the client application and be called once you log, you can do this with a listener or Shiro Grails controller that performs user authentication.


  • Install the plugin in the application
grails install-plugin /path/plgin/
  • Set the names of the models and properties used in Config.groovy
securityConfig.userLookup.usernamePropertyName = 'username' //username property
securityConfig.userLookup.userDomainClassName = 'ShiroUser' //domain classname without package
securityConfig.userLookup.authorityJoinClassName = 'UserRole' //domain classname without package
securityConfig.userLookup.authority.className = 'ShiroRole' //domain classname without package
  • Declare the service ShiroActivitiSessionService and call the method attachUsername2Session() Once you have logged (probably in the AuthController Shiro - Line 45 -)

List All Tasks

The plugin for Grails Activiti task contains three views (myTasks, unassignedTasks and AllTasks), in the latter view (in version 5.7 of the plugin) default are not users can execute the tasks, it is necessary to amend allTaskList.gsp the scriptlet that begins on line 66 with the following code:

def users = []
def userList=[:]
def userIds = ActivitiUtils.activitiService.getCandidateUserIds(
def groups
def groupIds
if (!applicationContext.getBean('pluginManager').hasGrailsPlugin('activitiSpringSecurity')) 
	def User = grailsApplication.getDomainClass(grailsApplication.config.securityConfig.userLookup.userDomainClassName).clazz
	users = User."findAllBy${GrailsNameUtils.getClassNameRepresentation(grailsApplication.config.securityConfig.userLookup.usernamePropertyName)}InList"(userIds)
	for (id in userIds) 
		groups = ActivitiUtils.identityService.createGroupQuery().groupMember(id).orderByGroupId().asc().list()
	def User = grailsApplication.getDomainClass(grailsApplication.config.grails.plugins.springsecurity.userLookup.userDomainClassName).clazz
	users = User."findAllBy${GrailsNameUtils.getClassNameRepresentation(grailsApplication.config.grails.plugins.springsecurity.userLookup.usernamePropertyName)}InList"(userIds)
for (user in users) 
	groups = ActivitiUtils.identityService.createGroupQuery().groupMember(
	groupIds = groups?" ${groups.collect{}}":""





29/11/2011 - Initial Release

  • Implemented IdentityService initialization with UserManager and GroupManager
  • Implemented shuttle username in session
  • Test-integration with Grails Activiti VacationRequest