Jump to: navigation, search

Stardust/Knowledge Base/Security/Authentication/User and Department Synchronization

Introduction

This article explains the usage of custom login and participant synchronization providers for integrating a user base in an external repository with the Stardust AuditTrail. It is assumed that the reader has a basic understanding of the Synchronization provider mechanism exposed in Stardust.

Note: All artifacts referenced in this article may be downloaded from here.

Model Organization Structure

The model organization structure used in this example is as follows:

Stardust Security Authentication UserDeptSync Image 1.gif

Here Country, City, and Branch are scoped organizations.

Custom Login Provider

package com.sungard.user.repo;
 
import java.util.Map;
 
import ag.carnot.security.authentication.LoginFailedException;
import ag.carnot.workflow.spi.security.ExternalLoginProvider;
import ag.carnot.workflow.spi.security.ExternalLoginResult;
 
public class MyExternalLoginProvider implements ExternalLoginProvider{
 
 
 
	public ExternalLoginResult login(String userID, String pwd, Map properties) {
 
		System.out.println("userID:" + userID);
		System.out.println("pwd:" + pwd);
 
		if(ExternalRepositoryWrapper.isUserValid(userID, pwd)){		
			return ExternalLoginResult.testifySuccess();
		}else{
			return ExternalLoginResult.testifyFailure(new LoginFailedException("Not a valid user.", 2));
		}
	}
 
 
}

Note that ExternalRepositoryWrapper is a facade used for all required communication with the external user repository. It encapsulates the repository connection details (whether LDAP or DB or properties file) and abstracts this away from the Stardust runtime.

Custom Participant Synchronization Login Provider

package com.sungard.user.repo;
 
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import ag.carnot.workflow.spi.security.DynamicParticipantSynchronizationProvider;
import ag.carnot.workflow.spi.security.ExternalDepartmentConfiguration;
import ag.carnot.workflow.spi.security.ExternalUserConfiguration;
 
import com.sungard.user.repo.ExternalRepositoryWrapper.User;
 
public class MyDynamicParticipantSynchronizationProvider extends
		DynamicParticipantSynchronizationProvider {
 
	@Override
	public ExternalUserConfiguration provideUserConfiguration(String accont) {
		System.out.println("In side provideUserConfiguration: accont :"
				+ accont);
 
		final User user = ExternalRepositoryWrapper.getUser(accont);
		System.out.println("User found:" + user);
		if (user == null) {
			return null;
		} else {
			System.out.println("In side else: user is:" + user.getAccount());
			return new ExternalUserConfiguration() {
 
				@Override
				public String getDescription() {
					// TODO Auto-generated method stub
					return null;
				}
 
				@Override
				public String getEMail() {
					// TODO Auto-generated method stub
					return null;
				}
 
				@Override
				public String getFirstName() {
					// TODO Auto-generated method stub
					return user.getName();
				}
 
				@Override
				public String getLastName() {
					// TODO Auto-generated method stub
					return user.getName();
				}
 
				@Override
				public Map getProperties() {					
					return null;
				}
 
				/**
				 * IPP will use the returned set of GrantInfo to sync and create the user and
				 * departments.
				 * Note that the overridden method provideDepartmentConfiguration() will called by IPP 
				 * only when it finds/sees GrantInfo object with not-empty/not-null department list.
				 * If GrantInfo object is not having valid department list, method provideDepartmentConfiguration
				 * will never be invoked by IPP
				 * 
				 * @return
				 */
				@Override
				public Set<GrantInfo> getModelParticipantsGrants() {
					/*
					 * get the user department/organization info for given role from external user repository 
					   and pass as List<String> to GrantInfo object.
					*/ 
					Set<GrantInfo> set = new HashSet<GrantInfo>();					
					for(String role : user.getAuths().keySet()){
						GrantInfo gi = new GrantInfo(role, ExternalRepositoryWrapper.getUserDepartmentHierarchy(user.account, role));
						set.add(gi);
					}					
					return set;
				}
 
				/**
				 * This deprecated method, use getModelParticipantsGrants method.
				 * @return
				 */
				@Override
				public Set<GrantInfo> getGrantedModelParticipants(){
					return null;
				}	
 
			};
		}
 
	}
 
	/* IPP will create/sync the department in the audit-trail returned by this method.
	 */
	@Override
	public ExternalDepartmentConfiguration provideDepartmentConfiguration(final String participantId,
			final List<String> departmentKey)
	   {
		    return new ExternalDepartmentConfiguration(){
				@Override
				public String getDescription() {
					return null;
				}	
				@Override
				public String getName() {
					if(departmentKey != null && departmentKey.size() !=0){
						return departmentKey.get(departmentKey.size() -1);
					}
					return null;
				}
 
		    };
	   }
 
}

Note that the overridden method getModelParticipantsGrants creates a GrantInfo object for each user role that includes a department list fetched from the external repository. The Stardust runtime calls the overridden method provideDepartmentConfiguration for each department encountered in the GrantInfo object returned.

Note: For completeness, an implementation of the the ExternalRepositoryWrapper class that uses static data has been provided here. In practice this class would interact with LDAP repository or a database to fetch user and participant information.

Running the Example

Setup a RAD project,and include the downloaded Login and Participant Sync Provider clases. Once the Stardust portal is up and running, follow the instructions given below:

  • Deploy downloaded model with user "motu" as usual through the RAD environment or via the Model Management view of the Administration perspective of the portal.
  • Login with user id/password "emp3/emp3". Once login is successful, this user will be synced with its departments into the AuditTrail database.
  • To make sure this user (emp3, named as "RaviShankar") is synchronized with its departments, login with user "motu", go to the Participant Management view and see if this user is assigned to the scoped role employee, under the department USA->NYC->Manhattan.