Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

A Session Controller Authorization plugin, is responsible for providing information which will be used for authorization of users.

Plugins supplied with Ceptor PortalProtect standard distribution

By default, the following authorization plugins are supplied:

  • dk.itp.security.passticket.server.ConfigBasedAuthorizationPlugin
    Reads ACLs and protected URLs from the session controllers configuration properties. 
  • dk.itp.security.passticket.server.FileAuthorizationPlugin
    Reads list of protected URLs, ACLs and Groups from the file system.
  • dk.itp.security.ldap.LdapAuthorizationPlugin
    Reads ACLs, protected URLs and Groups from an LDAP server. 
  • dk.itp.portalprotect.useradmin.server.UAAuthorizationPlugin
    Reads ACLs, and Groups from the UserAdmin Database - supports searching for users and looking up a users group for use in administration - e.g. used by the WebLogic SSPI Plugins when Integrating with Oracle WebLogic.

Developing an Authorization Plugin

The are a couple of interfaces which an Authorization Plugin can or must implement;

...

This plugin implements fetching users and groups from the User administration Administration database using the Useradmin UserAdmin API. It demonstrates the functionality of an authorization plugin.

This sample plugin reads the list of protected URLs from a file called protectedurls.txt and groups and ACLs from the database.

Code Block
languagejava
titleSample UAAuthorizationPlugin
package dk.portalprotect.sample.plugins;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dk.itp.portalprotect.useradmin.data.Acl;
import dk.itp.portalprotect.useradmin.data.Challenge;
import dk.itp.portalprotect.useradmin.data.Group;
import dk.itp.portalprotect.useradmin.data.QuickUser;
import dk.itp.portalprotect.useradmin.data.User;
import dk.itp.pp.useradmin.client.IUserAdmin;
import dk.itp.pp.useradmin.client.UserAdminAgent;
import dk.itp.pp.useradmin.client.UserAdminException;
import dk.itp.security.authorization.IAuthorizationPlugin;
import dk.itp.security.authorization.IAuthorizationPluginUserGetter;
import dk.itp.security.authorization.client.ACLEntry;
import dk.itp.security.authorization.client.GroupEntry;
import dk.itp.security.authorization.client.OperationNotSupportedException;
import dk.itp.security.authorization.client.PermissionEntry;
import dk.itp.security.authorization.client.URLEntry;
import dk.itp.security.authorization.client.UserEntry;
import dk.itp.security.passticket.AuthTypes;
import dk.itp.security.passticket.PTException;

/**
 * This Authorization plugin reads usergroups from the useradmin database, 
 * and, acls and protected URLs from files.
 * 
 * @author Kim Rasmussen
 * @version $Revision$
 * 
 * <pre>
 * PortalProtect - Security infrastructure
 * Copyright(c) 2001, IT Practice A/S, All rights reserved.
 * 
 * This source code is confidential.
 * </pre>
 */
public class UAAuthorizationPlugin implements IAuthorizationPlugin, IAuthorizationPluginUserGetter {
	private Vector protectedURLs;
	private static Logger log = LoggerFactory.getLogger(UAAuthorizationPlugin.class);

	/**
	 * @see IAuthorizationPlugin#getACLsForUser(String)
	 */
	public Vector getACLsForUser(String principal) throws OperationNotSupportedException {
		throw new OperationNotSupportedException("Not supported");
	}

	/**
	 * @see IAuthorizationPlugin#getAuthorizationType()
	 */
	public int getAuthorizationType() {
		return AuthTypes.AUTHORIZATIONTYPE_USERADMINISTRATION;
	}

	/**
	 * @see IAuthorizationPlugin#getAvailableACLs(String)
	 */
	public Vector getAvailableACLs(String identifier) throws OperationNotSupportedException {
		Vector ret = new Vector();
		Hashtable ht = new Hashtable();
		
		IUserAdmin ua = UserAdminAgent.getInstance();
		
		try {
			Acl[] acls = ua.listAcls();
		
			for(int i = 0; i < acls.length; i++) {
				String name = acls[i].getName();
				String permission = "*";
				int ofs = name.lastIndexOf('.');
				
				if (ofs >= 0) {
					permission = name.substring(ofs+1);
					name = name.substring(0, ofs);
				}
				
				ACLEntry entry = (ACLEntry)ht.get(name);
				if (entry == null) {
					entry = new ACLEntry(name);
					ht.put(name, entry);
					ret.addElement(entry);
				}
				PermissionEntry pe = new PermissionEntry(permission);
				entry.addPermission(pe);
				
				Group[] groups = acls[i].getGroups();
				for( int n = 0; groups != null && n < groups.length; n++) {
					Group grp = groups[n];
					pe.addMember(grp.getName());
				}
				
				QuickUser[] users = acls[i].getUsers();
				for( int n = 0; users != null && n < users.length; n++) {
					QuickUser usr = users[n];
					pe.addMember("uid:"+usr.getID());
				}
			}
		} catch (Throwable e) {
			log.error("Unable to read acls from UserAdmin server", e);
		}
		return ret;
	}

	/**
	 * @see IAuthorizationPlugin#getAvailableGroups(String)
	 */
	public Vector getAvailableGroups(String identifier) throws OperationNotSupportedException {
		Vector usergroups = new Vector();

		IUserAdmin ua = UserAdminAgent.getInstance();
		
		try {
			Group[] groups = ua.getAllGroups();
			for(int i = 0; i < groups.length; i++) {
				GroupEntry entry = new GroupEntry(groups[i].getName(), groups[i].getName());
				
				// Do not fill in the list of group members, since group membership is stored
				// on the individual user record, since it scales a lot better than storing all users that are
				// member of a group in the group itself.
				
				usergroups.addElement(entry);
			}
		} catch (Throwable e) {
			log.error("Unable to read user groups from UserAdmin server", e);
		}
		
		return usergroups;
	}

	/**
	 * @see IAuthorizationPlugin#getName()
	 */
	public String getName() {
		return "Useradmin DB authorization plugin";
	}
	
	/**
	 * Returns known users for the given criterias.<br>
	 * Note that this method is most suited for exposing known users to an administration interface, like weblogics portal administration.
	 * @param wildcard The wildcard to match, could be * or part of the username/id
	 * @param groupName If not null, searches for users within the specified group
	 * @param searchSpec Additional search parameters, can be used for limiting searches if not null
	 * @param maxReturns Maximum number of user entries to return
	 * @param identifier Either identifies the server name, or null for non-server specific
	 * @return Vector of UserEntry records
	 * @throws PTException. This is thrown if some error occurs.
	 */
	public Vector getAvailableUsers(String wildcard, String groupName, String searchSpec, int maxReturns, String identifier) throws PTException {
		Vector users = new Vector();

		IUserAdmin ua = UserAdminAgent.getInstance();
		
		try {
			Challenge[] challenges = ua.searchChallenges(wildcard.replace('*', '%'), groupName, maxReturns);
			for(int i = 0; i < challenges.length; i++) {
				UserEntry entry = new UserEntry(challenges[i].getLogonID(), null);
				users.addElement(entry);
			}
		} catch (Throwable e) {
			log.error("Unable to read user groups from UserAdmin server", e);
		}
		
		return users;
	}
	

	/**
	 * @see IAuthorizationPlugin#getSpecificACL(String, String)
	 */
	public Object getSpecificACL(String identifier, String name) throws OperationNotSupportedException {
		Vector v = getAvailableACLs(identifier);
		if (v == null)
			return null;
			
		Enumeration enumeration = v.elements();
		while(enumeration.hasMoreElements()) {
			ACLEntry entry = (ACLEntry)enumeration.nextElement();
			
			if (entry.getName().equals(name))
				return entry;
		}
		
		return null;
	}

	/**
	 * @see IAuthorizationPlugin#getSpecificGroup(String, String)
	 */
	public Object getSpecificGroup(String identifier, String name) throws OperationNotSupportedException {
		IUserAdmin ua = UserAdminAgent.getInstance();
		
		try {
			Group[] groups = ua.getAllGroups();
			for(int i = 0; i < groups.length; i++) {
				if (name.equals(groups[i].getName()))
					return new GroupEntry(groups[i].getName(), groups[i].getName());
			}
		} catch (Throwable e) {
			log.error("Unable to read user groups from UserAdmin server", e);
		}
		
		return null;
	}

	/**
	 * @see IAuthorizationPlugin#getProtectedURLs(String)
	 */
	public Vector getProtectedURLs(String identifier) throws OperationNotSupportedException {
		return protectedURLs;
	}

	/**
	 * @see IAuthorizationPlugin#setConfiguration(Properties)
	 */
	public void setConfiguration(Properties props) {
		System.getProperties().setProperty("useradmin.server", props.getProperty("useradminservers", "localhost:15000"));

		String userid = props.getProperty("ua_userid", "userid");
		String password = props.getProperty("ua_credentials", "password");

		try {
			UserAdminAgent.getInstance().login(userid, password);
		} catch (UserAdminException e) {
			log.error("Unable to login to user administration", e);
		}
		
		protectedURLs = new Vector();

		String filename = props.getProperty("protectedUrlsFile", "protectedurls.txt");
		log.info("Reading protected URLs from " + filename);
		FileReader fr = null;
		try {
			fr = new FileReader(filename);
			BufferedReader br = new BufferedReader(fr);
			String line = br.readLine();
			while (line != null) {
				while (line != null && line.trim().length() == 0)
					line = br.readLine();
				if (line == null)
					break;

				String url = line.trim();
				URLEntry entry = new URLEntry(url);
				// Now, read the permissions required to access this URL - they are all indented at least one whitespace
				// when the next line does not start with a whitespace, it is probably another URL

				do {
					line = br.readLine();
					while (line != null && line.trim().length() == 0)
						line = br.readLine();
					if (line == null)
						break;
					if (!Character.isWhitespace(line.charAt(0))) {
						break;
					}
					entry.addPrincipal(line.trim());
				}
				while (line != null && Character.isWhitespace(line.charAt(0)));
				protectedURLs.addElement(entry);
				log.info("Added protected URL: " + entry);
			}

			log.info("Finished reading URLs");
		} catch (Exception e) {
			log.error("Unable to read protected URLs", e);
		} finally {
			if (fr != null)
				try {
					fr.close();
				} catch (IOException e) {}
		}
	}

	/**
	 * @see IAuthorizationPlugin#getStatusText()
	 */
	public String getStatusText() {
		return null;
	}

	/**
	 * @see dk.itp.security.authorization.IAuthorizationPluginUserGetter#getUserGroups(java.lang.String)
	 */
	public String[] getUserGroups(String userid) throws PTException, OperationNotSupportedException {
		try {
			User user = UserAdminAgent.getInstance().getUser(userid, -1);
			Group[] groups = UserAdminAgent.getInstance().getGroups(user.getID());
			String[] result = new String[groups.length];
			for(int i = 0; i < groups.length; i++) {
				result[i] = groups[i].getName();
			}
			return result;
		} catch(UserAdminException e) {
			if (e.getErrorCode() == UserAdminException.ERROR_NOROWSFOUND)
				return new String[0];
			log.warn("Problem reading users groups, user: " + userid, e);
			
			// Don't throw a UserAdminException, since the client (which is probably a weblogic realm) does not have this exception class)
			throw new PTException(e.toString(), e.getErrorCode(), e.getErrorText());
		}
	}
}