页面树结构
转至元数据结尾
转至元数据起始

使用AD域登录示例,请先查看 《与第三方系统用户集成》的第 4、使用第三方系统的用户验证

AD域登录示例
package smartbi.usermanager.auth.impl;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.servlet.ServletContext;
import org.apache.log4j.Logger;
import smartbi.usermanager.auth.*;
import smartbi.util.StringUtil;
/**
 * 此类为使用Microsoft的AD(活动目录)登录验证的一个例子。<br>
 * 需要配置文件ad.properties,并放入到war包中的WEB-INF目录中,配置文件中包含的键值为:<br>
 * 
 * <pre>
 * # 上下文对象工厂类,一般不需要改变
 * 		initial_context_factory=com.sun.jndi.ldap.LdapCtxFactory
 * # 活动目录的访问地址
 * 	provider_url=ldap://ADServer:3268
 * # 活动目录的登录用户名前缀
 * 		principal_prefix=MyDomain\\
 * # 活动目录的登录用户名
 * 	login_user=username
 * # 活动目录的登录密码
 * 	login_password=password
 * </pre>
 */
public class ADAuthentication implements IAuthentication {
	private static final Logger log = Logger.getLogger(ADAuthentication.class);
	private String initialContextFactory;
	private String providerUrl;
	private String prefix;
	private String loginUser;
	private String loginPassword;
	private String baseName;
	private String filterPrefix;
	private String filterSuffix;
	/**
	 * 配置登录验证类
	 * 
	 * @param ctx
	 *            应用的上下文对象
	 * @throws IOException
	 *             当出现初始化错误时。
	 */
	public void config(ServletContext ctx) throws IOException {
		init(ctx.getResourceAsStream("/WEB-INF/ad.properties"));
	}
	/**
	 * 读取必要的配置信息
	 * 
	 * @param is
	 *            配置文件
	 * @throws IOException
	 *             当读取配置文件出错时抛出
	 */
	private void init(InputStream is) throws IOException {
		if (is != null) {
			Properties prop = new Properties();
			prop.load(is);
			initialContextFactory = prop.getProperty("initial_context_factory");
			providerUrl = prop.getProperty("provider_url");
			prefix = prop.getProperty("principal_prefix");
			loginUser = prop.getProperty("login_user");
			loginPassword = prop.getProperty("login_password");
			baseName = StringUtil.nullToEmpty(prop.getProperty("baseName"));
			filterPrefix = StringUtil.nullToEmpty(prop.getProperty("filterPrefix"));
			filterSuffix = StringUtil.nullToEmpty(prop.getProperty("filterSuffix"));
			is.close();
		}
	}
	/**
	 * 判断登录用户名、密码是否正确
	 * 
	 * @param userName
	 *            用户名
	 * @param password
	 *            密码
	 * @return 如果登录成功则返回true,如果失败则返回false
	 * @throws IOException
	 *             当出现通信异常
	 */
	public boolean isPasswordValidate(String userName, String password) throws IOException {
		if (StringUtil.isNullOrEmpty(password)) {
			return false;
		}
		try {
			Hashtable<String, String> env = initEnv(userName, password);
			LdapContext context = new InitialLdapContext(env, null);
			context.close();
			return true;
		} catch (NamingException e) {
			return false;
		}
	}
	/**
	 * 初始化访问活动目录所需要的参数设置
	 * 
	 * @param userName
	 *            登录活动目录的用户名
	 * @param password
	 *            登录活动目录的密码
	 * @return 返回相应的参数配置
	 */
	private Hashtable<String, String> initEnv(String userName, String password) {
		Hashtable<String, String> env = new Hashtable<String, String>();
		env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
		env.put(Context.PROVIDER_URL, providerUrl);
		env.put(Context.SECURITY_PRINCIPAL, prefix + userName);
		env.put(Context.SECURITY_CREDENTIALS, password);
		return env;
	}
	/**
	 * 获取用户的名称、别名信息
	 * 
	 * @param userName
	 *            用户名
	 * @return 指定用户的信息
	 * @throws IOException
	 *             当出现通信异常
	 * @throws UserNotExistException
	 *             如果抛出此异常,则smartbi会删除此用户
	 */
	public UserInfo getUser(String userName) throws IOException, UserNotExistException {
		try {
			// AD-使用配置文件中的用户名、密码登录
			Hashtable<String, String> env = initEnv(loginUser, loginPassword);
			LdapContext context = new InitialLdapContext(env, null);
			// baseName 可以通过Softerra LDAP Browser查看
			String base = baseName;
			// AD-指定搜索范围为个人,并且用户名为客户端输入的用户名称
			String filter = filterPrefix + userName + filterSuffix;
			SearchControls controls = new SearchControls();
			controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			// AD-返回用户的名称、别名及部门
			controls.setReturningAttributes(new String[] { "sAMAccountName", "displayName", "department" });
			NamingEnumeration<SearchResult> answer = context.search(base, filter, controls);
			if (answer.hasMore()) {
				// 如果找到相应的用户
				SearchResult result = answer.next();
				Attributes attrs = result.getAttributes();
				Attribute attr = attrs.get("sAMAccountName");
				String name = attr == null || attr.get() == null ? null : attr.get().toString();
				attr = attrs.get("displayName");
				String alias = attr == null || attr.get() == null ? null : attr.get().toString();
				attr = attrs.get("department");
				String dept = attr == null || attr.get() == null ? null : attr.get().toString();
				answer.close();
				// 设置用户信息,smartbi会自动同步
				UserInfo info = new UserInfo(name, alias, alias);
				// 设置组信息
				GroupInfo group = new GroupInfo();
				group.setName(dept);
				// 设置组的父组为null,即此组会建立在smartbi的"默认组"之下
				// 如果不为null,smartbi会根据此属性来建立用户组的树结构
				group.setParentGroup(null);
				// smartbi支持一个用户同时属于多个用户组,所以使用List<GroupInfo>
				List<GroupInfo> groups = new ArrayList<GroupInfo>();
				groups.add(group);
				// 设置用户所属的组
				info.setGroups(groups);
				// AD不支持返回角色列表,所以设置角色为null,smartbi不会修改此用户所属的角色
				info.setRoles(null);
				return info;
			}
			// 如果用户不存在,则抛出异常
			throw new UserNotExistException(userName);
		} catch (NamingException e) {
			log.error("getUser fail.", e);
			return null;
		}
	}
	/**
	 * 返回用户是否在本Authentication类中验证密码
	 * 
	 * @param userName
	 *            用户名
	 * @return 如果返回true,表示该用户的密码在本类中验证;如果返回false,表示该用户的密码在知识库中验证
	 * @throws IOException
	 *             当出现通信异常
	 */
	public boolean shallUserValidateInAuthentication(String userName) throws IOException {
		// admin用户还是使用知识库本身的方式验证
		if ("admin".equals(userName))
			return false;
		else
			return true;
	}
	/**
	 * 设置用户的密码
	 * 
	 * @param oldPassword
	 *            旧密码
	 * @param newPassword
	 *            新密码
	 * @return 返回设置用户密码是否成功
	 * @throws IOException
	 *             当出现通信异常时抛出
	 * @throws UnsupportedOperationException
	 *             当该用户验证类不支持此操作时抛出
	 */
	public boolean changePassword(String userName, String oldPassword, String newPassword) throws IOException,
			UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}
}
  • 无标签