1、重写 net.jforum.sso.LDAPAuthenticator 类
package net.jforum.sso;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import net.jforum.dao.UserDAO;
import net.jforum.entities.User;
import net.jforum.util.preferences.ConfigKeys;
import net.jforum.util.preferences.SystemGlobals;
/**
* Authenticate users against a LDAP server.
*
* @author Rafael Steil
* @version $Id: LDAPAuthenticator.java,v 1.8 2006/08/20 22:47:43 rafaelsteil Exp $
*/
public class LDAPAuthenticator implements LoginAuthenticator
{
private Hashtable prepareEnvironment()
{
Hashtable h = new Hashtable();
h.put(Context.INITIAL_CONTEXT_FACTORY, SystemGlobals.getValue(ConfigKeys.LDAP_FACTORY));
h.put(Context.PROVIDER_URL, SystemGlobals.getValue(ConfigKeys.LDAP_SERVER_URL));
String protocol = SystemGlobals.getValue(ConfigKeys.LDAP_SECURITY_PROTOCOL);
if (protocol != null && !"".equals(protocol.trim())) {
h.put(Context.SECURITY_PROTOCOL, protocol);
}
String authentication = SystemGlobals.getValue(ConfigKeys.LDAP_AUTHENTICATION);
if (authentication != null && !"".equals(authentication.trim())) {
h.put(Context.SECURITY_AUTHENTICATION, authentication);
}
return h;
}
/**
* @see net.jforum.sso.LoginAuthenticator#validateLogin(java.lang.String, java.lang.String, java.util.Map)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public User validateLogin(String username, String password, Map extraParams)
{
Hashtable environment = this.prepareEnvironment();
environment.put(Context.SECURITY_PRINCIPAL, getRDN(username));
environment.put(Context.SECURITY_CREDENTIALS, password);
DirContext dir = null;
try {
dir = new InitialDirContext(environment);
Attribute att = dir.getAttributes(getRDN(username)).get(SystemGlobals.getValue(ConfigKeys.LDAP_FIELD_EMAIL));
SSOUtils utils = new SSOUtils();
if (!utils.userExists(username)) {
String email = att != null ? (String)att.get() : "noemail";
utils.register("ldap", email);
}
return utils.getUser();
}
catch (AuthenticationException e) {
return null;
}
catch (NamingException e)
{
return null;
}
finally {
if (dir != null) {
try
{
dir.close();
}
catch (NamingException e)
{
//close jndi context
}
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private String getRDN(String username){
String rst = "";
try {
// 连接 LDAP 服务器,获取目录服务器上下文对象 InitialDirContext
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, SystemGlobals.getValue(ConfigKeys.LDAP_FACTORY));
env.put(Context.PROVIDER_URL, SystemGlobals.getValue(ConfigKeys.LDAP_SERVER_URL));
InitialDirContext ctx = new InitialDirContext(env);
// 创建一个查询组件
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); // 搜索范围指定
String searchFilter = "(cn="+username+")"; // 搜索条件
String searchBase = "ou=people,dc=mengtaigroup,dc=com"; // 搜索起点
String returnedAtts[] = { "cn" }; // 指定返回哪些属性字段
searchCtls.setReturningAttributes(returnedAtts); // 设置搜索组建的返回属性
// 执行查询
NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);
// 遍历查询结果集及记录属性
if (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
rst = sr.getNameInNamespace();
}
} catch (NamingException e) {
e.printStackTrace();
}
return rst;
}
/**
* @see net.jforum.sso.LoginAuthenticator#setUserModel(net.jforum.dao.UserDAO)
*/
public void setUserModel(UserDAO dao)
{
}
}
2、修改配置文件 /WEB-INF/config/SystemGlobals.properties
authentication.type = default
login.authenticator = net.jforum.sso.LDAPAuthenticator
auto.login.enabled = true
# #######
# LDAP
# #######
# Security protocol to use, e.g: "ssl"
# Leave it empty (default) to let the provider figure it out
ldap.security.protocol =
# Security authentication to use. Possible values: "none", "simple", "strong",
# "EXTERNAL" (SASL). Leave empty (default) to let the provider figure it out
ldap.authentication = simple
# Class that provides a LDAP factory
ldap.factory = com.sun.jndi.ldap.LdapCtxFactory
# The prefix your LDAP server requires. e.g 'uid='
# The username supplied gets inserted just after the prefix,
# e.g: 'uid=username' so adjust the prefix properly
ldap.login.prefix = cn=
# The suffix your LDAP server requires.
# e.g 'ou=Users,dc=department,dc=company,dc=com'
ldap.login.suffix =
# The url of your LDAP server.
# Notice that if your LDAP server uses SSL you will need to configure your
# server certificate so that Java Secure Sockets Extension (JSSE) will accept it.
# Read http://java.sun.com/products/jndi/tutorial/ldap/security/ssl.html
ldap.server.url = ldap://192.168.0.122:1389
# Field that holds the user's email
ldap.field.email = mail
# ActiveDirectory
# To configure LDAPAuthenticator integrating with Microsoft Active Directory. The following two keys should be necessary.
# They are similar to ldap.login.prefix and ldap.login.suffix , but it's used when looking up user infomation
# rather than authentication. It's used when the login Distinguished Name (DN) is formatted differently from the lookup
# DN on some LDAP servers, for example, Microsoft Active Directory. If it's the case, you should add these keys in additional
# to ldap.login.prefix and ldap.login.suffix .
#
# The following example is for configuring on Microsoft Active Directory:
# ===========================
# ldap.login.prefix=CN=
# ldap.login.suffix=CN=Users,DC=jform,DC=net
# ldap.lookup.suffix=CN=Users
# ===========================
ldap.lookup.prefix =
ldap.lookup.suffix =
PS:
A. 修正用户注册时显示的用户协议乱码的问题 /templates/agreement/terms_zh_CN.txt 转化为UTF-8
B. 修正发布新贴和回复按钮透明的问题 /home/guo/workspace_mt/jforum/WebContent/templates/default/images 加入
/home/guo/workspace_mt/jforum/WebContent/templates/gpl_icons 中的文件夹 zh_TW