Securing the Stardust Engine

This section summarizes the configuration issues when integrating Stardust into an existing security infrastructure. For an in-depth discussion of the underlying concepts, see the Programming Guide.

Note: Server side properties described in the configurations below are meant to be set in the server side carnot.properties. Client side properties have to be set in the client side carnot.properties.

Authentication and Authorization Choices

Authentication

Authentication can be done in one of the following modes:

The following table summarizes the different authentication options.

  Custom Registry Spring Local Mode Client Bean Factory
Internal Login no yes no
Implicit Login yes no yes
JAAS Login yes yes no

Authorization

Authorization in Stardust, i.e. the assignment of participants (roles/organizations) to users is normally stored in the audit trail. If an external user registry is used the authorization information has to be replicated from the external registry every time a login is done. This role mapping logic has to be implemented by providing an implementation of the

org.eclipse.stardust.engine.core.spi.security.DynamicParticipantSynchronizationProvider

interface. The details for implementing a synchronization provider can be found in the Programming Guide.

Internal Authentication

Internal authentication mode is turned on by default when no security related properties are explicitly set. It always uses the audit trail database as authentication and authorization source. You can document the use of internal authentication explicitly by setting the following property on the server:

Security.Authentication.Mode = internal

The following table summarizes other server side configuration options for internal authentication:

Property Range/Default Value Remarks
Security.Authentication.Mode String / internal internal authentication mode
Security.Authentication.MaximumNumberLoginRetries integer / 3 A re-login try threshold. If exceeded the account is temporarily disabled
Security.Authentication.InvalidationTimeInMinutes integer / 1 min The time an account is disabled after unsuccessful login

Deploying Stateless Beans

Please note that in case you like to perform a stateless deployment for internal authentication you have to adjust some settings in your deployment descriptor. Please refer to the section Stateless Bean Deployment for Internal Authentication of the chapter Deploying Stardust Components to an EJB Application Server in the Deployment Guide for detailed information.

Implicit Authentication

Server configuration

Implicit authentication is turned on by setting the following server side property:

Security.Authentication.Mode = principal.

If you use an external user registry you also have to configure participant synchronization (see below).

Java Client Configuration

Configuring a Stardust Java client for implicit authentication means specifying the secure session factory and the credential provider to be used. The Secure.Session.Factory client side property should contain the name of a class implementing the org.eclipse.stardust.engine.api.ejb2.SecureSessionFactory interface, while correspondingly the Credential.Provider property must contain the name of a class extending the org.eclipse.stardust.engine.api.runtime.CredentialProvider class.

Also, you have to provide the necessary JAAS configuration file. The content of the configuration file must be conforming to the specifications of the application server used. The configuration file should be specified according to the JAAS standards, either in the client JVM security properties, placed in the user home path or by explicitly providing the configuration file path in the JVM system property java.security.auth.login.config.

By default, the security configuration is named carnot. If necessary, you can specify another security configuration by providing the corresponding name in the Security.Authentication.ConfigurationName client side property.

Stardust provides security examples with source code for example implementations. Refer to the Examples section for details.

WebLogic example

For a WebLogic authentication example, download the following zip file:

This example provides a secure session factory for WebLogic, that you can use by setting the property Secure.Session.Factory in your carnot.properties file:

Secure.Session.Factory = org.eclipse.stardust.examples.authentication.weblogic.WeblogicSecureSessionFactory

WebSphere example

For a WebSphere authentication example, download the following zip file:

This example provides a secure session factory and a credential provider for WebSphere, that you can use by setting the properties Secure.Session.Factory and Credential.Provider in your carnot.properties file:

Credential.Provider = org.eclipse.stardust.examples.authentication.websphere.WASCredentialProvider
Secure.Session.Factory = org.eclipse.stardust.examples.authentication.websphere.WASSecureSessionFactory

Web Client Configuration

No Stardust specific configuration has to be done because the principal association is a matter of the servlet container setup.

JAAS Authentication

Server Configuration

Server side JAAS Authentication is set by:

 Security.Authentication.Mode = jaas

Additionally, you have to provide the following properties:

Property Range / Default Value Remarks
Security.Authentication.
ConfigurationName
String / - The JAAS login configuration name
Security.Authentication.PrincipalClass String / - The class name of the principal to use from the returned JAAS Subject

You also have to set up a login configuration in the server configuration itself. Please refer to your application server security documentation for detailed information on how to do this. Note, that the exact method of authentication tried depends on the credentials present in the JAAS subject and the JAAS configuration set by the application.

Client Configuration

The JAAS authentication mode is transparent to the client. No configuration is necessary.

Participant Synchronization

Participant synchronization has to be done if authentication is done against an authentication source different from the audit trail database. The Stardust Process Engine then has to synchronize the participant mappings at login time. The configuration to be provided is the name of the SynchronizationProvider to use, and probably provider specific settings:

 Security.Authorization.SynchronizationProvider = classname

To control the frequency of participant synchronization, Stardust evaluates the property:

 Security.Authorization.SynchronizationStrategy = classname

The strategy implementation has to be an implementation of the interface:

 org.eclipse.stardust.engine.core.spi.security.DynamicParticipantSynchronizationStrategy  

By implementing this interface it is possible to tell the engine if a specific dynamic participant's external representation is likely to have been, thus requiring a new synchronization operation. By default the class:

 org.eclipse.stardust.engine.core.spi.security.TimebasedSynchronizationStrategy

is used, which itself by default synchronizes any participant only every 10 seconds. This delay may be configured by setting the properties:

 Security.Authorization.TimebasedSynchronizationStrategy.UserSyncTimeout

and

 Security.Authorization.TimebasedSynchronizationStrategy.UserGroupSyncTimeout

to the desired number of seconds.

If you want to invalidate a user or usergroup, which does not exist in external registry, you can set the following property:

Security.Authorization.InvalidateNonexistingParticipants

The validTo property of the non-existing user or usergroup will then be set to current date.

To enable tracing for user or usergroup synchronization with external registry evaluate the following property:

Security.Authorization.TraceSynchronization

Participant synchronization is transparent to Stardust clients. It only has to be configured on the server side.

LDAP Synchronization Example

The LDAP synchronization example located in the examples/ldap-sync directory is maybe useful to you if you have to synchronize against an LDAP repository and if you can express the user-to-participant mapping by an LDAP search filter.

This provider can be configured using the following properties:

Property Range/
Default Value
Remarks
LDAPSynchronization.ServerName Hostname / - The host name of the LDAP server to connect
LDAPSynchronization.ServerPort Port number / 389 The port number to connect
LDAPSynchronization.RootDN LDAP distinguished name The distinguished name where all operations are relative to
LDAPSynchronization.BindMode 'anonymous' or 'dedicated' /'anonymous' Flag indicating whether to connect anonymously
LDAPSynchronization.BindUserDN String User DN to use for connecting if bind mode is dedicated
LDAPSynchronization.BindPassword String Password to use for connecting if bind mode is dedicated
LDAPSynchronization.SearchTimeLimit Integer /
0 (unlimited)
The time limit for searches in milliseconds
LDAPSynchronization.UserFilter LDAP search filter The search filter to get user information for a principal name. The wildcard %v is used to include the principal name.
LDAPSynchronization.ParticipantFilter LDAP search filter The search filter to get the participants for a principal name. The wildcard %v is used to include the principal name.
LDAPSynchronization.
ParticipantNamingAttribute
LDAP attribute name/'cn' The attribute name for getting the Stardust participant ID from a found participant

As an example here is a configuration which:

Security.Authorization.SynchronizationProvider = org.eclipse.stardust.examples.authorization.ldap.LDAPSynchronizationProvider
LDAPSynchronization.ServerName=ldap.de.carnot.ag LDAPSynchronization.RootDN=dc=de,dc=carnot,dc=ag,dc=test LDAPSynchronization.UserFilter="(&(uid=%v)(objectclass=inetOrgPerson)) LDAPSynchronization.ParticipantFilter=(&(objectClass=groupOfUniqueNames)(uniqueMember=uid=%v*))

Java 2 Security

If you want to enforce Java 2 Security in your application server you have to relax somehow the permissions mandated in the J2EE specification to allow access to Stardust resources. Also, Stardust uses advanced Java reflection you have to permit.

Here are the permissions you have to set to operate CANROT:

 java.io.FilePermission "carnot-engine.jar" "read";

to read resources from the Stardust jar:

 permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
 permission java.lang.RuntimePermission "accessDeclaredMembers";

to allow advanced Java reflection.

Dependent on the JAXP implementation your application server is using you may need additional permissions, like

permission:

 java.io.FilePermission "xalan.jar", "read";

If you intend to use Stardust mail functionality (notifications or triggers) you also have to relax the permissions to get access to JDK specific mail resources.

Setting Application Permissions

Predefined Permissions

The following table shows the service operations provided by Stardust depending on the model element and the permission to be used:

Model Element Permission/Default Participant Service Operations concerned
Model Deploy and Modify Process Model/Administrator AdministrationService.deployModel
AdministrationService.modifyModel
AdministrationService.overwriteModel
Model Modify Audit Trail Content/Administrator AdministrationService.cleanupRuntime
AdministrationService.cleanupRuntimeAndModels
Model Run Recovery/Administrator AdministrationService.recoverProcessInstances
AdministrationService.recoverRuntimeEnvironment
Model Manage Daemons/Administrator AdministrationService.getDaemon
AdministrationService.startDaemon
AdministrationService.stopDaemon
Model Control process engine/Administrator AdministrationService.flushCashes
Model Obtain Audit Trail Statistics/Administrator AdministrationService.getAuditTrailHealthReport
QueryService.getLogEntriesCount(LogEntryQuery query)
QueryService.findFirstLogEntry(LogEntryQuery query)
QueryService.getAllLogEntries(LogEntryQuery query)
Model Obtain User Data/Administrator QueryService.getAllUserGroups(UserGroupQuery query)
QueryService.getAllUsers(UserQuery query)
QueryService.getUserGroupsCount(UserGroupQuery query)
QueryService.getUsersCount(UserQuery query)
QueryService.findFirstUser(UserQuery query)
QueryService.findFirstUserGroup(UserGroupQuery query)
UserService.getUser(String account)
UserService.getUser(String realm, String account)
UserService.getUser(long userOID)
UserService.getUserGroup(String id)
UserService.getUserGroup(long oid)
UserService.getUserRealms()
Model Modify User Data/Administrator UserService.modifyUser(User user)
UserService.createUser(String account, String firstName, String lastName, String description, String password, String eMail, Date validFrom, Date validTo)
UserService.createUser(String realm, String account, String firstName, String lastName, String description, String password, String eMail, Date validFrom, Date validTo)
UserService.invalidateUser(String account)
UserService.invalidateUser(String realm, String account)
UserService.createUserGroup(String id, String name, String description, Date validFrom, Date validTo)
UserService.modifyUserGroup(UserGroup userGroup)
UserService.invalidateUserGroup(String id)
UserService.invalidateUserGroup(long oid)
UserService.createUserRealm(String id, String name, String description)
UserService.dropUserRealm(String id)
Model Obtain Model Data/All QueryService.getProcessDefinition(long modelOID, String id)
QueryService.getProcessDefinition(String id)
QueryService.getModel(long modelOID)
QueryService.getModel(long modelOID, boolean computeAliveness)
QueryService.getModels(DeployedModelQuery query)
QueryService.getModelAsXML(long modelOID)
QueryService.getModelDescription(long modelOID)
QueryService.getActiveModel() (deprecated)
QueryService.getActiveModelDescription()
QueryService.getAllProcessDefinitions()
QueryService.getAllProcessDefinitions(long modelOID)
QueryService.getAllAliveModelDescriptions()
QueryService.getAllParticipants()
QueryService.getAllParticipants(long modelOID)
QueryService.getParticipant(long modelOID, String id)
QueryService.getAllModelDescriptions()
QueryService.wasRedeployed(long modelOid, int revision)
QueryService.getParticipant(String id)
Model Read Departments AdministrationService.getDepartment(long oid)
Model Modify Departments AdministrationService.createDepartment(String id, String name, String description, DepartmentInfo parent, OrganizationInfo organization)
AdministrationService.modifyDepartment(long oid, String name, String description)
AdministrationService.removeDepartment(long oid)
Process Definition Start Process/Implicitly via manual trigger WorkflowService.startProcess(String id, Map data, boolean synchronously)
Process Definition Abort Process Instances/Administrator AdministrationService.abortProcessInstance
WorkflowService.abortProcessInstance(long processInstanceOID)
Process Definition Delete Process Instances/Administrator AdministrationService.deleteProcesses
Process Definition Read Process Instance Data/Administrator QueryService.getAllProcessInstances(ProcessInstanceQuery query)
QueryService.findFirstProcessInstance(ProcessInstanceQuery query)
QueryService.getProcessInstancesCount(ProcessInstanceQuery query)
Process Definition Manage Event Handlers/Administrator WorkflowService.getProcessInstanceEventHandler(long processInstanceOID, String handler)
WorkflowService.bindProcessEventHandler(long processInstanceOID, EventHandlerBinding eventHandler)
WorkflowService.bindProcessEventHandler(long processInstanceOID, String handler)
WorkflowService.unbindProcessEventHandler(long processInstanceOID, String handler)
Data Read Data Values/All
Activity Perform Activity Permission/Implicitly via performer assignment WorkflowService.getWorklist(WorklistQuery query)
WorkflowService.getActivityInstance(long activityInstanceOID)
WorkflowService.abortActivityInstance(long activityInstanceOID)
WorkflowService.abortActivityInstance(long activityInstanceOid, AbortScope abortScope)
WorkflowService.activate(long activityInstanceOID)
WorkflowService.activateAndComplete(long activityInstanceOID, String context, Map outData)
WorkflowService.activateAndComplete(long activityInstanceOID, String context, Map outData, int flags)
WorkflowService.activateNextActivityInstance(long activityInstanceOID)
WorkflowService.activateNextActivityInstanceForProcessInstance(long processInstanceOID)
WorkflowService.complete(long activityInstanceOID, String context, Map outData)
WorkflowService.complete(long activityInstanceOID, String context, Map outData, int flags)
WorkflowService.hibernate(long activityInstanceOID)
WorkflowService.suspendToUser(long activityInstanceOID)
Activity Delegation to other users WorkflowService.delegateToDefaultPerformer(long activityInstanceOID)
WorkflowService.delegateToParticipant(long activityInstanceOID, String performer)
WorkflowService.delegateToParticipant(long activityInstanceOID, ParticipantInfo participant)
WorkflowService.delegateToUser(long activityInstanceOID, long userOID)
WorkflowService.suspendToDefaultPerformer(long activityInstanceOID)
WorkflowService.suspendToDefaultPerformer(long activityInstanceOID, String context, Map outData)
WorkflowService.suspendToParticipant(long activityInstanceOID, String participant)
WorkflowService.suspendToParticipant(long activityInstanceOID, String participant, String context, Map outData)
WorkflowService.suspendToParticipant(long activityInstanceOID, ParticipantInfo participant, ContextData outData)
WorkflowService.hibernate(long activityInstanceOID)
WorkflowService.suspend(long activityInstanceOID, ContextData outData)
WorkflowService.suspendToUser(long activityInstanceOID, long userOID)
WorkflowService.suspendToUser(long activityInstanceOID, long userOID, String context, Map outData)
WorkflowService.suspendToUser(long activityInstanceOID, String context, Map outData)
Activity Manage Event Handlers/Administrator WorkflowService.getActivityInstanceEventHandler(long activityInstanceOID, String handler)
WorkflowService.bindActivityEventHandler(long activityInstanceOID, EventHandlerBinding eventHandler)
WorkflowService.bindActivityEventHandler(long activityInstanceOID, String handler)
WorkflowService.unbindActivityEventHandler(long activityInstanceOID, String handler)
Activity Read Activity Instance Data/All QueryService.findFirstActivityInstance(ActivityInstanceQuery query)
QueryService.getAllActivityInstances(ActivityInstanceQuery query)
QueryService.getActivityInstancesCount(ActivityInstanceQuery query)
QueryService.getAuditTrail(long processInstanceOID)

For a detailed description on the permissions for specific services, refer to chapter Declarative Security Usage in Stardust Services API in the Programming Guide.

Service Methods restricted to OWNER

The grant OWNER is either the user, the user group, or the model participant that is currently assigned as performer of an activity instance. The following methods of the WorkflowService are restricted to the OWNER by the means of the activity.performActivity permission, which is fixed and cannot be changed by the modeler:

If the current user does not qualify as an OWNER of the activity instance, an AccessForbiddenException will be thrown.

The following two methods require the current user to become the OWNER of the next activity instance:

If that is not possible, because the permission is denied, a value of null is returned and no authorization specific exception will be thrown.

Service Methods restricted to Administrator

The method AdministrationService.forceCompletion is restricted to the Administrator by the means of the activity.performActivity permission, which is fixed and cannot be changed by the modeler.

If the current user does not qualify as an Administrator, an AccessForbiddenException will be thrown.

Service Methods without Permission

The following service methods can be executed without permission: