jndiauthenticationstore.java

来自「Rapla是一个灵活的多用户资源管理系统。它提供的一些功能有:日历GUI」· Java 代码 · 共 984 行 · 第 1/3 页

JAVA
984
字号
     *
     * @exception NamingException if a directory server error occurs
     */
    protected boolean compareCredentials(DirContext context,
                                         JNDIUser info,
                                         String credentials)
        throws NamingException {

        if (info == null || credentials == null)
            return (false);

        String password = info.password;
        if (password == null)
            return (false);

        // Validate the credentials specified by the user
        if ( getLogger().isDebugEnabled() )
            log("  validating credentials");

        boolean validated = false;
        if (hasMessageDigest()) {
            // Hex hashes should be compared case-insensitive
            validated = (digest(credentials).equalsIgnoreCase(password));
        } else {
            validated = (digest(credentials).equals(password));
        }

        return (validated);

    }

    protected boolean hasMessageDigest() {
        return !(md == null);
    }


    /**
     * Digest the password using the specified algorithm and
     * convert the result to a corresponding hexadecimal string.
     * If exception, the plain credentials string is returned.
     *
     * <strong>IMPLEMENTATION NOTE</strong> - This implementation is
     * synchronized because it reuses the MessageDigest instance.
     * This should be faster than cloning the instance on every request.
     *
     * @param credentials Password or other credentials to use in
     *  authenticating this username
     */
    protected String digest(String credentials)  {

        // If no MessageDigest instance is specified, return unchanged
        if ( hasMessageDigest() == false)
            return (credentials);

        // Digest the user credentials and return as hexadecimal
        synchronized (this) {
            try {
                md.reset();
                md.update(credentials.getBytes());
                return (Tools.convert(md.digest()));
            } catch (Exception e) {
                log("realmBase.digest", e);
                return (credentials);
            }
        }
    }

    /**
     * Check credentials by binding to the directory as the user
     *
     * @param context The directory context
     * @param user The User to be authenticated
     * @param credentials Authentication credentials
     *
     * @exception NamingException if a directory server error occurs
     */
     protected boolean bindAsUser(DirContext context,
                                  JNDIUser user,
                                  String credentials)
         throws NamingException {
         
         if (credentials == null || user == null)
             return (false);

         String dn = user.dn;
         if (dn == null)
             return (false);

         // Validate the credentials specified by the user
         if ( getLogger().isDebugEnabled() ) {
             log("  validating credentials by binding as the user");
        }

        // Set up security environment to bind as the user
        context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn);
        context.addToEnvironment(Context.SECURITY_CREDENTIALS, credentials);

        // Elicit an LDAP bind operation
        boolean validated = false;
        try {
            if ( getLogger().isDebugEnabled() ) {
                log("  binding as "  + dn);
            }
            //Attributes attr = 
            context.getAttributes("", null);
            validated = true;
        }
        catch (AuthenticationException e) {
            if ( getLogger().isDebugEnabled() ) {
                log("  bind attempt failed" + e.getMessage());
            }
        }

        // Restore the original security environment
        if (connectionName != null) {
            context.addToEnvironment(Context.SECURITY_PRINCIPAL,
                                     connectionName);
        } else {
            context.removeFromEnvironment(Context.SECURITY_PRINCIPAL);
        }

        if (connectionPassword != null) {
            context.addToEnvironment(Context.SECURITY_CREDENTIALS,
                                     connectionPassword);
        }
        else {
            context.removeFromEnvironment(Context.SECURITY_CREDENTIALS);
        }

        return (validated);
     }


    /**
     * Return a String representing the value of the specified attribute.
     *
     * @param attrId Attribute name
     * @param attrs Attributes containing the required value
     *
     * @exception NamingException if a directory server error occurs
     */
    private String getAttributeValue(String attrId, Attributes attrs)
        throws NamingException {

        if ( getLogger().isDebugEnabled() )
            log("  retrieving attribute " + attrId);

        if (attrId == null || attrs == null)
            return null;

        Attribute attr = attrs.get(attrId);
        if (attr == null)
            return (null);
        Object value = attr.get();
        if (value == null)
            return (null);
        String valueString = null;
        if (value instanceof byte[])
            valueString = new String((byte[]) value);
        else
            valueString = value.toString();

        return valueString;
    }


    /**
     * Close any open connection to the directory server for this Realm.
     *
     * @param context The directory context to be closed
     */
    protected void close(DirContext context) {

        // Do nothing if there is no opened connection
        if (context == null)
            return;

        // Close our opened connection
        try {
            if ( getLogger().isDebugEnabled() )
                log("Closing directory context");
            context.close();
        } catch (NamingException e) {
            log("jndiRealm.close", e);
        }
        this.context = null;

    }


    /**
     * Open (if necessary) and return a connection to the configured
     * directory server for this Realm.
     *
     * @exception NamingException if a directory server error occurs
     */
    protected DirContext open() throws NamingException {

        // Do nothing if there is a directory server connection already open
        if (context != null)
            return (context);

        try {

            // Ensure that we have a directory context available
            context = new InitialDirContext(getDirectoryContextEnvironment());

        } catch (NamingException e) {

            connectionAttempt = 1;

            // log the first exception.
            log("jndiRealm.exception", e);

            // Try connecting to the alternate url.
            context = new InitialDirContext(getDirectoryContextEnvironment());

        } finally {

            // reset it in case the connection times out.
            // the primary may come back.
            connectionAttempt = 0;

        }

        return (context);

    }

    /**
     * Create our directory context configuration.
     *
     * @return java.util.Hashtable the configuration for the directory context.
     */
    protected Hashtable getDirectoryContextEnvironment() {

        Hashtable env = new Hashtable();

        // Configure our directory context environment.
        if ( getLogger().isDebugEnabled() && connectionAttempt == 0)
            log("Connecting to URL " + connectionURL);
        env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
        if (connectionName != null)
            env.put(Context.SECURITY_PRINCIPAL, connectionName);
        if (connectionPassword != null)
            env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
        if (connectionURL != null && connectionAttempt == 0)
            env.put(Context.PROVIDER_URL, connectionURL);

        return env;

    }

    // ------------------------------------------------------ Lifecycle Methods


    /**
     * Prepare for active use of the public methods of this Component.
     *
     * @exception LifecycleException if this component detects a fatal error
     *  that prevents it from being started
     */
    public void start() throws Exception {
        // Create a MessageDigest instance for credentials, if desired
        if (digest != null) {
            md = MessageDigest.getInstance(digest);
        }
        // Validate that we can open our connection
        open();
        // Perform normal superclass initialization
    }


    /**
     * Gracefully shut down active use of the public methods of this Component.
     *
     * @exception LifecycleException if this component detects a fatal error
     *  that needs to be reported
     */
    public void stop() throws Exception {
        // Close any open directory server connection
        close(this.context);

    }

    public static void main(String[] args) {
        JNDIAuthenticationStore aut = new JNDIAuthenticationStore();
        aut.enableLogging(new ConsoleLogger());
        aut.setConnectionName( "cn=Manager,dc=einfachanders" );
        aut.setConnectionPassword( "rapla2003" );
        aut.setConnectionURL( "ldap://localhost:389" );
        //aut.setUserPassword ( "userPassword" );
        aut.setUserBase ( "ou=people,dc=einfachanders" );
        aut.setUserSearch (" (uid={0})" );
        try {
            aut.start();
            if ( aut.authenticate ( "admin", "test" ) ) {
                System.out.println( "Authentication succeeded." );
            } else {
                System.out.println( "Authentication failed" );
            }
        } catch (Exception ex ) {
            ex.printStackTrace();
        }
    }

    /**
     * A private class representing a User
     */
    static class JNDIUser {
        String username = null;
        String dn = null;
        String password = null;
        String mail = null;
        String cn = null;

        JNDIUser(String username, String dn, String password, String mail, String cn) {
            this.username = username;
            this.dn = dn;
            this.password = password;
            this.mail = mail;
            this.cn = cn;
        }

    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?