jndiauthenticationstore.java
来自「Rapla是一个灵活的多用户资源管理系统。它提供的一些功能有:日历GUI」· Java 代码 · 共 984 行 · 第 1/3 页
JAVA
984 行
/*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.rapla.plugin.jndi;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
import org.rapla.components.util.Tools;
import org.rapla.entities.Category;
import org.rapla.framework.RaplaException;
import org.rapla.storage.AuthenticationStore;
/**
* This Plugin is based on the jakarta.apache.org/tomcat JNDI Realm
* and enables the authentication of a rapla user against a JNDI-Directory.
* The most commen usecase is LDAP-Authentication, but ActiveDirectory
* may be possible, too.
* <li>Each user element has a distinguished name that can be formed by
* substituting the presented username into a pattern configured by the
* <code>userPattern</code> property.</li>
* </li>
*
* <li>The user may be authenticated by binding to the directory with the
* username and password presented. This method is used when the
* <code>userPassword</code> property is not specified.</li>
*
* <li>The user may be authenticated by retrieving the value of an attribute
* from the directory and comparing it explicitly with the value presented
* by the user. This method is used when the <code>userPassword</code>
* property is specified, in which case:
* <ul>
* <li>The element for this user must contain an attribute named by the
* <code>userPassword</code> property.
* <li>The value of the user password attribute is either a cleartext
* String, or the result of passing a cleartext String through the
* <code>digest()</code> method (using the standard digest
* support included in <code>RealmBase</code>).
* <li>The user is considered to be authenticated if the presented
* credentials (after being passed through
* <code>digest()</code>) are equal to the retrieved value
* for the user password attribute.</li>
* </ul></li>
*
*/
public class JNDIAuthenticationStore extends AbstractLogEnabled implements AuthenticationStore,Startable {
// ----------------------------------------------------- Instance Variables
/**
* Digest algorithm used in storing passwords in a non-plaintext format.
* Valid values are those accepted for the algorithm name by the
* MessageDigest class, or <code>null</code> if no digesting should
* be performed.
*/
protected String digest = null;
/**
* The MessageDigest object for digesting user credentials (passwords).
*/
protected MessageDigest md = null;
/**
* The connection username for the server we will contact.
*/
protected String connectionName = null;
/**
* The connection password for the server we will contact.
*/
protected String connectionPassword = null;
/**
* The connection URL for the server we will contact.
*/
protected String connectionURL = null;
/**
* The directory context linking us to our directory server.
*/
protected DirContext context = null;
/**
* The JNDI context factory used to acquire our InitialContext. By
* default, assumes use of an LDAP server using the standard JNDI LDAP
* provider.
*/
protected String contextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
/**
* The attribute name used to retrieve the user password.
*/
protected String userPassword = null;
/**
* The attribute name used to retrieve the user email.
*/
protected String userMail = null;
/**
* The attribute name used to retrieve the complete name of the user.
*/
protected String userCn = null;
/**
* The base element for user searches.
*/
protected String userBase = "";
/**
* The message format used to search for a user, with "{0}" marking
* the spot where the username goes.
*/
protected String userSearch = null;
/**
* The MessageFormat object associated with the current
* <code>userSearch</code>.
*/
protected MessageFormat userSearchFormat = null;
/**
* The number of connection attempts. If greater than zero we use the
* alternate url.
*/
protected int connectionAttempt = 0;
public JNDIAuthenticationStore(Configuration config,Logger logger) throws ConfigurationException{
enableLogging( logger);
setDigest( config.getAttribute( "digest", null ) );
setConnectionName( config.getAttribute( "connectionName" ) );
setConnectionPassword( config.getAttribute( "connectionPassword", null) );
setConnectionURL( config.getAttribute( "connectionURL" ) );
setContextFactory( config.getAttribute( "contextFactory", contextFactory ) );
setUserPassword( config.getAttribute( "userPassword", null ) );
setUserMail( config.getAttribute( "userMail", null ) );
setUserCn( config.getAttribute( "userCn", null ) );
setUserSearch( config.getAttribute( "userSearch") );
setUserBase( config.getAttribute( "userBase") );
}
public JNDIAuthenticationStore() {
}
private void log( String message,Exception ex ) {
getLogger().error ( message, ex );
}
private void log( String message ) {
getLogger().debug ( message );
}
public String getName() {
return ("JNDIAuthenticationStore with contectFactory " + contextFactory );
}
/**
* Set the digest algorithm used for storing credentials.
*
* @param digest The new digest algorithm
*/
public void setDigest(String digest) {
this.digest = digest;
}
public boolean isCreateUserEnabled() {
return true;
}
/** queries the user and initialize the name and the email field. */
public boolean initUser( org.rapla.entities.User user, String username, String password, Category userGroupCategory)
throws RaplaException
{
boolean modified = false;
JNDIUser intUser = authenticateUser( username, password );
if ( intUser == null )
throw new RaplaException("Can't authenticate user " + username);
String oldUsername = user.getUsername();
if ( oldUsername == null || !oldUsername.equals( username ) ) {
user.setUsername( username );
modified = true;
}
String oldEmail = user.getEmail();
if ( intUser.mail != null && (oldEmail == null || !oldEmail.equals( intUser.mail ))) {
user.setEmail( intUser.mail );
modified = true;
}
String oldName = user.getName();
if ( intUser.cn != null && (oldName == null || !oldName.equals( intUser.cn )) ) {
user.setName( intUser.cn );
modified = true;
}
return modified;
}
/**
* Set the connection username for this Realm.
*
* @param connectionName The new connection username
*/
public void setConnectionName(String connectionName) {
this.connectionName = connectionName;
}
/**
* Set the connection password for this Realm.
*
* @param connectionPassword The new connection password
*/
public void setConnectionPassword(String connectionPassword) {
this.connectionPassword = connectionPassword;
}
/**
* Set the connection URL for this Realm.
*
* @param connectionURL The new connection URL
*/
public void setConnectionURL(String connectionURL) {
this.connectionURL = connectionURL;
}
/**
* Set the JNDI context factory for this Realm.
*
* @param contextFactory The new context factory
*/
public void setContextFactory(String contextFactory) {
this.contextFactory = contextFactory;
}
/**
* Set the password attribute used to retrieve the user password.
*
* @param userPassword The new password attribute
*/
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
/**
* Set the mail attribute used to retrieve the user mail-address.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?