I've added some more debug code to the LDAP auth class.. Can you send me
a full log file to check it out..
If this does not give more info I suggest debugging..
Ludovic
Peter Murray wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 8/12/05 3:05 PM, Ludovic Dubost wrote:
Right.. I had the feeling an email address would
not work.. The fact
that there is no page yet in the wiki should not be a problem at this
point..
Okay -- we'll need to work around that at some point because most of my
folks log in with an e-mail address (just a few of us have non-email
UIDs in the LDAP directory). First, though, I'd like to fix this
challenge, then worry about that.
I don't get why you get no message between
these two:
DEBUG LDAPAuthServiceImpl:Bind:451 - LDAP Bind successfull INFO
MyFormAuthenticator:processLogin:142 - User peter login has failed
'tis true, 'tis true. For me it ranks right up there with trying to
figure out how I got to line 142 of MyFormAuthenticator.
There should be at least one.. when I look at the
code I put to give
some debut messages
What is your LDAP server by the way ?
OpenLDAP (latest version -- just installed it).
Peter
- --
Peter Murray
http://www.pandc.org/peter/work/
Assistant Director, Multimedia Systems tel:+1-614-728-3600;ext=338
OhioLINK: the Ohio Library and Information Network Columbus, Ohio
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Darwin)
Comment: Using GnuPG with Thunderbird -
http://enigmail.mozdev.org
iD8DBQFC/i8r4+t4qSfPIHIRAlZ5AJ4jJUlPNWIiWrJWQhmdb20tlJ+zBwCgxJ13
wp1UQgLQPAXQQkX0KTUVgz8=
=02y/
-----END PGP SIGNATURE-----
------------------------------------------------------------------------
--
You receive this message as a subscriber of the xwiki-users(a)objectweb.org mailing list.
To unsubscribe: mailto:xwiki-users-unsubscribe@objectweb.org
For general help: mailto:sympa@objectweb.org?subject=help
ObjectWeb mailing lists service home page:
http://www.objectweb.org/wws
--
Ludovic Dubost
XPertNet:
http://www.xpertnet.fr/
Blog:
http://www.ludovic.org/blog/
XWiki:
http://www.xwiki.com
Skype: ldubost AIM: nvludo Yahoo: ludovic
package com.xpn.xwiki.user.impl.LDAP;
import com.xpn.xwiki.user.impl.xwiki.*;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.objects.classes.BaseClass;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.doc.XWikiDocument;
import com.novell.ldap.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.lang.StringUtils;
import org.securityfilter.realm.SimplePrincipal;
import java.security.Principal;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.text.MessageFormat;
/**
* Created by IntelliJ IDEA.
* User: Alex
* Date: 18 avr. 2005
* Time: 16:18:50
* To change this template use File | Settings | File Templates.
*/
public class LDAPAuthServiceImpl extends XWikiAuthServiceImpl {
private static final Log log = LogFactory.getLog(LDAPAuthServiceImpl.class);
public Principal authenticate(String username, String password, XWikiContext context)
throws XWikiException {
Principal principal = null;
if ((username==null)||(username.trim().equals("")))
return null;
if ((password==null)||(password.trim().equals("")))
return null;
String superadmin = "superadmin";
if (username.equals(superadmin)) {
String superadminpassword =
context.getWiki().Param("xwiki.superadminpassword");
if ((superadminpassword!=null)&&(superadminpassword.equals(password)))
{
principal = new SimplePrincipal("XWiki.superadmin");
return principal;
} else {
return null;
}
}
// If we have the context then we are using direct mode
// then we should specify the database
// This is needed for virtual mode to work
if (context!=null) {
String susername = username;
int i = username.indexOf(".");
if (i!=-1)
susername = username.substring(i+1);
String DN = getLDAP_DN(susername, context);
if (DN != null && DN.length()!=0)
{
if (checkDNPassword(DN, susername, password, context))
{
principal = GetUserPrincipal(susername, context);
}
}
else
{
HashMap attributes = new HashMap();
if (checkUserPassword(susername, password, attributes, context))
{
principal = GetUserPrincipal(susername, context);
if (principal == null && attributes.size() > 0)
{
CreateUserFromLDAP(susername, attributes, context);
principal = GetUserPrincipal(susername, context);
}
}
}
}
return principal;
}
private void CreateUserFromLDAP(String susername, HashMap attributes, XWikiContext
context) throws XWikiException {
String ldapFieldMapping = getParam("ldap_fields_mapping",context);
if (ldapFieldMapping != null && ldapFieldMapping.length() > 0)
{
String[] fields = ldapFieldMapping.split(",");
BaseClass bclass = context.getWiki().getUserClass(context);
BaseObject bobj = new BaseObject();
bobj.setClassName(bclass.getName());
String name = null;
String fullwikiname = null;
for(int i = 0; i < fields.length; i++ )
{
String[] field = fields[i].split("=");
if (2 == field.length)
{
String fieldName = field[0];
if (attributes.containsKey(field[1]))
{
String fieldValue;
fieldValue = (String)attributes.get(field[1]);
if (fieldName.equals("name"))
{
name = fieldValue;
fullwikiname = "XWiki." + name;
bobj.setName(fullwikiname);
}
else
{
bobj.setStringValue(fieldName, fieldValue);
}
}
}
}
if (name != null && name.length() > 0)
{
XWikiDocument doc = context.getWiki().getDocument(fullwikiname, context);
doc.setParent("");
doc.addObject(bclass.getName(), bobj);
doc.setContent("#includeForm(\"XWiki.XWikiUserTemplate\")");
context.getWiki().ProtectUserPage(context, fullwikiname, "edit",
doc);
context.getWiki().saveDocument(doc, null, context);
context.getWiki().SetUserDefaultGroup(context, fullwikiname);
}
}
}
protected Principal GetUserPrincipal(String susername, XWikiContext context) {
Principal principal = null;
// First we check in the local database
try {
String user = findUser(susername, context);
if (user!=null) {
principal = new SimplePrincipal(user);
}
} catch (Exception e) {}
if (context.isVirtual()) {
if (principal==null) {
// Then we check in the main database
String db = context.getDatabase();
try {
context.setDatabase(context.getWiki().getDatabase());
try {
String user = findUser(susername, context);
if (user!=null)
principal = new SimplePrincipal(context.getDatabase() +
":" + user);
} catch (Exception e) {}
} finally {
context.setDatabase(db);
}
}
}
return principal;
}
public String getLDAP_DN(String susername, XWikiContext context)
{
String DN=null;
if (context!=null) {
// First we check in the local database
try {
String user = findUser(susername, context);
if (user!=null && user.length()!=0) {
DN = readLDAP_DN(user, context);
}
} catch (Exception e) {}
if (context.isVirtual()) {
if (DN==null && DN.length()!=0) {
// Then we check in the main database
String db = context.getDatabase();
try {
context.setDatabase(context.getWiki().getDatabase());
try {
String user = findUser(susername, context);
if (user!=null && user.length()!=0)
DN = readLDAP_DN(user, context);
} catch (Exception e) {}
} finally {
context.setDatabase(db);
}
}
}
}
return DN;
}
private String readLDAP_DN(String username, XWikiContext context) {
String DN = null;
try {
XWikiDocument doc = context.getWiki().getDocument(username, context);
// We only allow empty password from users having a XWikiUsers object.
if (doc.getObject("XWiki.XWikiUsers")!=null) {
DN = doc.getStringValue("XWiki.XWikiUsers", "ldap_dn");
}
} catch (Throwable e) {}
return DN;
}
protected boolean checkUserPassword(String username, String password, HashMap
attributes, XWikiContext context) throws XWikiException {
LDAPConnection lc = new LDAPConnection();
boolean result = false;
boolean notinLDAP = false;
String foundDN = null;
try {
if (log.isDebugEnabled())
log.debug("LDAP Password check for user " + username);
int ldapPort = getLDAPPort(context);
int ldapVersion = LDAPConnection.LDAP_V3;
String ldapHost = getParam("ldap_server", context);
String bindDNFormat = getParam("ldap_bind_DN",context);
String bindPasswordFormat = getParam("ldap_bind_pass",context);
int checkLevel = GetCheckLevel(context);
Object[] arguments = {
username,
password
};
String bindDN = MessageFormat.format(bindDNFormat, arguments);
String bindPassword = MessageFormat.format(bindPasswordFormat, arguments);
String baseDN = getParam("ldap_base_DN",context);
lc.connect( ldapHost, ldapPort );
if (log.isDebugEnabled())
log.debug("LDAP Connect successfull to host " + ldapHost +
" and port " + ldapPort );
// authenticate to the server
result = Bind(bindDN, bindPassword, lc, ldapVersion);
if (log.isDebugEnabled())
log.debug("LDAP Bind returned");
if (result && checkLevel > 0)
{
if (log.isDebugEnabled())
log.debug("LDAP searching user");
LDAPSearchResults searchResults =
lc.search( baseDN,
LDAPConnection.SCOPE_SUB ,
"("+ getParam("ldap_UID_attr",context)
+
"=" + username + ")",
null, // return all attributes
false); // return attrs and values
if (searchResults.hasMore())
{
if (log.isDebugEnabled())
log.debug("LDAP searching found user");
LDAPEntry nextEntry = searchResults.next();
foundDN = nextEntry.getDN();
if (log.isDebugEnabled())
log.debug("LDAP searching found DN: " + foundDN);
if (checkLevel > 1)
{
if (log.isDebugEnabled())
log.debug("LDAP comparing password");
LDAPAttribute attr = new LDAPAttribute(
"userPassword", password
);
result = lc.compare( foundDN, attr );
}
if (result)
{
if (log.isDebugEnabled())
log.debug("LDAP adding user attributes");
LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();
Iterator allAttributes = attributeSet.iterator();
while(allAttributes.hasNext()) {
LDAPAttribute attribute =
(LDAPAttribute)allAttributes.next();
String attributeName = attribute.getName();
Enumeration allValues = attribute.getStringValues();
if( allValues != null) {
while(allValues.hasMoreElements()) {
if (log.isDebugEnabled())
log.debug("LDAP adding user attribute "
+ attributeName);
String Value = (String) allValues.nextElement();
attributes.put(attributeName, Value);
}
}
}
attributes.put("dn", foundDN);
}
}
else {
if (log.isDebugEnabled())
log.debug("LDAP search user failed");
notinLDAP = true;
}
if (log.isInfoEnabled()) {
if (result)
log.info("LDAP Password check for user " + username +
" successfull");
else
log.info("LDAP Password check for user " + username +
" failed");
}
}
}
catch( LDAPException e ) {
if (log.isInfoEnabled())
log.info("LDAP Password check for user " + username + "
failed with exception " + e.getMessage());
if ( e.getResultCode() == LDAPException.NO_SUCH_OBJECT ) {
notinLDAP = true;
} else if ( e.getResultCode() ==
LDAPException.NO_SUCH_ATTRIBUTE ) {
notinLDAP = true;
}
}
catch (Throwable e) {
notinLDAP = true;
if (log.isErrorEnabled())
log.error("LDAP Password check for user " + username + "
failed with exception " + e.getMessage());
}
finally
{
if (log.isDebugEnabled())
log.debug("LDAP check in finally block");
try {
lc.disconnect();
} catch (LDAPException e) {
e.printStackTrace();
}
}
if (notinLDAP)
{
if (log.isDebugEnabled())
log.debug("LDAP Password check reverting to XWiki");
// Use XWiki password if user not in LDAP
result = checkPassword(username, password, context);
foundDN = null;
}
return result;
}
private String getParam(String name, XWikiContext context) {
String param = "";
try {
param = context.getWiki().getXWikiPreference(name,context);
} catch (Exception e) {}
if (param == null || "".equals(param))
{
try{
param = context.getWiki().Param("xwiki.authentication." +
StringUtils.replace(name, "ldap_","ldap."));
} catch (Exception e) {}
}
if (param == null)
param = "";
return param;
}
protected int GetCheckLevel(XWikiContext context)
{
String checkLevel = getParam("ldap_check_level", context);
int val = 2;
if ("1".equals(checkLevel))
val = 1;
else if ("0".equals(checkLevel))
val = 0;
return val;
}
private int getLDAPPort(XWikiContext context) {
try {
return context.getWiki().getXWikiPreferenceAsInt("ldap_port",
context);
} catch (Exception e) {
return
(int)context.getWiki().ParamAsLong("xwiki.authentication.ldap.port",
LDAPConnection.DEFAULT_PORT);
}
}
protected boolean checkDNPassword(String DN, String username, String password,
XWikiContext context) throws XWikiException {
LDAPConnection lc = new LDAPConnection();
boolean result = false;
boolean notinLDAP = false;
try {
int ldapPort = getLDAPPort(context);
int ldapVersion = LDAPConnection.LDAP_V3;
String ldapHost = getParam("ldap_server", context);
String bindDN = getParam("ldap_bind_DN",context);
String bindPassword = getParam("ldap_bind_pass",context);
String baseDN = getParam("ldap_base_DN",context);
lc.connect( ldapHost, ldapPort );
// authenticate to the server
result = Bind(DN, password, lc, ldapVersion);
if (log.isDebugEnabled()) {
if (result)
log.debug("(debug) Password check for user " + DN + "
successfull");
else
log.debug("(debug) Password check for user " + DN + "
failed");
}
}
catch( LDAPException e ) {
if ( e.getResultCode() == LDAPException.NO_SUCH_OBJECT ) {
notinLDAP = true;
} else if ( e.getResultCode() ==
LDAPException.NO_SUCH_ATTRIBUTE ) {
notinLDAP = true;
}
}
catch (Throwable e) {
e.printStackTrace();
}
finally
{
try {
lc.disconnect();
} catch (LDAPException e) {
e.printStackTrace();
}
}
if (notinLDAP)
{
// Use XWiki password if user not in LDAP
result = checkPassword(username, password, context);
}
return result;
}
private boolean Bind(String bindDN, String bindPassword, LDAPConnection lc, int
ldapVersion) throws UnsupportedEncodingException {
boolean bound = false;
if (log.isDebugEnabled())
log.debug("LDAP Bind starting");
if (bindDN != null && bindDN.length() > 0 && bindPassword !=
null)
{
try
{
lc.bind( ldapVersion, bindDN, bindPassword.getBytes("UTF8") );
bound = true;
if (log.isDebugEnabled())
log.debug("LDAP Bind successfull");
}
catch(LDAPException e) {
if (log.isErrorEnabled())
log.error("LDAP Bind failed with Exception " +
e.getMessage());
};
} else {
if (log.isDebugEnabled())
log.debug("LDAP Bind does not have binding info");
}
return bound;
}
}