Stardust/Knowledge Base/Security/Authentication/Property File Based User Login Provider

From Eclipsepedia

< Stardust‎ | Knowledge Base‎ | Security‎ | Authentication
Revision as of 08:15, 11 May 2012 by Ganesh.lawande.sungard.com (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

As you know, actual tasks/activities in Stardust are performed by users. These can be created in the Stardust using Admin perspective or Stardust can pull in the users from existing user repository like Exchange Server or any user store.

To achieve second option above, Stardust provides call back mechanism where we can provide our custom implementation to link users and credentials from existing system to Stardust roles and organizations.

This process is called as user synchronization. It has three parts. First is, authenticating users from external user registry. Second part is, synchronizing users along with their properties. And third is authorization of the users from external user repository. Even, there is forth part, applying a suitable strategy of when and how frequently users should be synced into Stardust. We will discuss this forth element in a separate article.

For Stardust, it doesn’t matter from which or what types of external user repository users are authenticated. The logic/code to pull users from external repo various, but once user data is fetched, how it is supplied to the Stardust engine remains constant.

In this article, to make our learning easier, we will use simple in-memory user store.

This article assumes that reader is already familiar with modeling basics and how user management and role assignment works in Stardust.


Contents

Our User Store

As promised, here is the user store, and all it is made up of is a single java class and a properties file.

users.properties

motu = Administrator
john = Employee
ken = Employee,Manager


Java Class

package com.sungard.user.repo;
 
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
 
import org.eclipse.stardust.engine.core.spi.security.ExternalLoginProvider;
import org.eclipse.stardust.engine.core.spi.security.ExternalLoginResult;
 
public class PropertiesFileBasedExternalUserRepository implements
		ExternalUserRepository, ExternalLoginProvider {
 
	static Properties users;
	static {
		users = new Properties();
		String propFileName = "users.properties";
		InputStream inputStream = PropertiesFileBasedExternalUserRepository.class
				.getClassLoader().getResourceAsStream(propFileName);
		try {
			if (inputStream == null) {
				throw new FileNotFoundException("property file '"
						+ propFileName + "' not found in the classpath");
			}
			users.load(inputStream);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
 
	public boolean authenticateUser(String user, String pwd)
			throws RuntimeException {
		if (users.getProperty(user) != null && user.equals(pwd)) {
			// In our case, password must be same as user id
			return true;
		}
		return false;
	}
 
	public User getUser(String user) throws RuntimeException {
		if (users.getProperty(user) != null) {
			User theUser = new User();
			theUser.setAccount(user);
			theUser.setName(user);
 
			//set the user grants			
			String roles = users.getProperty(user);
			Map<String, List<String>> userRoles = new HashMap<String, List<String>>();
			StringTokenizer stringTokenizer = new StringTokenizer(roles, ",");
			while (stringTokenizer.hasMoreTokens()){
				userRoles.put(stringTokenizer.nextToken(), null);
			}
 
			theUser.setAuths(userRoles);
			return theUser;
		} else
			return null;
	}
 
	public ExternalLoginResult login(String id, String password, Map properties) {
		boolean authenticateUser = authenticateUser(id, password);
		if (authenticateUser) {
			return ExternalLoginResult.testifySuccess();
		} else {
			return ExternalLoginResult.testifyFailure(null);
		}
 
	}
 
}

Authenticating the User

Once we have decide that we are going to use external user store (existing system) for user management, at Stardust end, all we need to do is write couple of call back classes and hook them into the Stardust.

To authenticate users, all we need to do is, implement a Stardust interface, ExteranlLogingProvider, which has only one method called login. And then, plug this class into the Stardust (as shown below), and that’s it. The stardust will start to delegate the authentication to this class.

For simplicity reason, we have implemented this interface as part of our user store class. See above.

Synchronizing User Details

Synchronizing User Grants

Hook in Our Code

To plug in our code in the Stardust, all we need to do is add the following entries in the carnot.perperties file.

#External user repository configuration
 
Security.Authentication.Mode = internal
Security.Authentication.LoginService = com.sungard.user.repo.PropertiesFileBasedExternalUserRepository
Security.Authorization.SynchronizationProvider = com.sungard.user.repo.PropertiesFileBasedDynamicParticipantSynchronizationProvider