jndiauthenticationstore.java

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

JAVA
984
字号
     */
    public void setUserMail(String userMail) {
        this.userMail = userMail;
    }
    /**
     * Set the password attribute used to retrieve the users completeName.
     */
    public void setUserCn(String userCn) {
        this.userCn = userCn;
    }

    /**
     * Set the base element for user searches.
     *
     * @param userBase The new base element
     */
    public void setUserBase(String userBase) {
        this.userBase = userBase;
    }

    /**
     * Set the message format pattern for selecting users in this Realm.
     *
     * @param userSearch The new user search pattern
     */
    public void setUserSearch(String userSearch) {
        this.userSearch = userSearch;
        if (userSearch == null)
            userSearchFormat = null;
        else
            userSearchFormat = new MessageFormat(userSearch);
    }


    // ---------------------------------------------------------- Realm Methods
    public boolean authenticate(String username, String credentials) {
        return authenticateUser( username, credentials ) != null;
    }
    
    /**
     * Return the Principal associated with the specified username and
     * credentials, if there is one; otherwise return <code>null</code>.
     *
     * If there are any errors with the JDBC connection, executing
     * the query or anything we return null (don't authenticate). This
     * event is also logged, and the connection will be closed so that
     * a subsequent request will automatically re-open it.
     *
     * @param username Username of the Principal to look up
     * @param credentials Password or other credentials to use in
     *  authenticating this username
     */
    private JNDIUser authenticateUser(String username, String credentials) {
        DirContext context = null;
        JNDIUser user = null;
        try {

            // Ensure that we have a directory context available
            context = open();

            // Occassionally the directory context will timeout.  Try one more
            // time before giving up.
            try {

                // Authenticate the specified username if possible
                user = authenticate(context, username, credentials);

            } catch (CommunicationException e) {


                // If contains the work closed. Then assume socket is closed.
                // If message is null, assume the worst and allow the
                // connection to be closed.
                if (e.getMessage()!=null &&
                    e.getMessage().indexOf("closed") < 0)
                    throw(e);

                // log the exception so we know it's there.
                log("jndiRealm.exception", e);

                // close the connection so we know it will be reopened.
                if (context != null)
                    close(context);

                // open a new directory context.
                context = open();

                // Try the authentication again.
                user = authenticate(context, username, credentials);

            }

            // Return the authenticated Principal (if any)
            return user;
        } catch (NamingException e) {

            // Log the problem for posterity
            log("jndiRealm.exception", e);

            // Close the connection so that it gets reopened next time
            if (context != null)
                close(context);

            // Return "not authenticated" for this request
            return null;
        }

    }


    // -------------------------------------------------------- Package Methods


    // ------------------------------------------------------ Protected Methods


    /**
     * Return the Principal associated with the specified username and
     * credentials, if there is one; otherwise return <code>null</code>.
     *
     * @param context The directory context
     * @param username Username of the Principal to look up
     * @param credentials Password or other credentials to use in
     *  authenticating this username
     *
     * @exception NamingException if a directory server error occurs
     */
    protected synchronized JNDIUser authenticate(DirContext context,
                                          String username,
                                          String credentials)
        throws NamingException {

        if (username == null || username.equals("")
            || credentials == null || credentials.equals(""))
            return (null);

        // Retrieve user information
        JNDIUser user = getUser(context, username);
        if (user != null  && checkCredentials(context, user, credentials))
            return user;
        
        return null;
    }


    /**
     * Return a User object containing information about the user
     * with the specified username, if found in the directory;
     * otherwise return <code>null</code>.
     *
     * If the <code>userPassword</code> configuration attribute is
     * specified, the value of that attribute is retrieved from the
     * user's directory entry. If the <code>userRoleName</code>
     * configuration attribute is specified, all values of that
     * attribute are retrieved from the directory entry.
     *
     * @param context The directory context
     * @param username Username to be looked up
     *
     * @exception NamingException if a directory server error occurs
     */
    protected JNDIUser getUser(DirContext context, String username)
        throws NamingException {
        JNDIUser user = null;
        // Get attributes to retrieve from user entry
        ArrayList list = new ArrayList();
        if (userPassword != null)
            list.add(userPassword);
        if (userMail != null)
            list.add(userMail);
        if (userCn != null)
            list.add(userCn);
        
        String[] attrIds = new String[list.size()];
        list.toArray(attrIds);
        // Use pattern or search for user entry
        user = getUserBySearch(context, username, attrIds);
        return user;
    }

    /**
     * Search the directory to return a User object containing
     * information about the user with the specified username, if
     * found in the directory; otherwise return <code>null</code>.
     *
     * @param context The directory context
     * @param username The username
     * @param attrIds String[]containing names of attributes to retrieve.
     *
     * @exception NamingException if a directory server error occurs
     */
    protected JNDIUser getUserBySearch(DirContext context,
                                           String username,
                                           String[] attrIds)
        throws NamingException {

        if (userSearchFormat == null) {
            getLogger().error("no userSearchFormat specied");
            return null;
        }

        // Form the search filter
        String filter = userSearchFormat.format(new String[] { username });

        // Set up the search controls
        SearchControls constraints = new SearchControls();

        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

        // Specify the attributes to be retrieved
        if (attrIds == null)
            attrIds = new String[0];
        constraints.setReturningAttributes(attrIds);

        if (getLogger().isDebugEnabled()) {
            log("  Searching for " + username);
            log("  base: " + userBase + "  filter: " + filter);
        }

        NamingEnumeration results =
            context.search(userBase, filter, constraints);


        // Fail if no entries found
        if (results == null || !results.hasMore()) {
            if (getLogger().isDebugEnabled()) {
                log("  username not found");
            }
            return (null);
        }

        // Get result for the first entry found
        SearchResult result = (SearchResult)results.next();

        // Check no further entries were found
        if (results.hasMore()) {
            log("username " + username + " has multiple entries");
            return (null);
        }

        // Get the entry's distinguished name
        NameParser parser = context.getNameParser("");
        Name contextName = parser.parse(context.getNameInNamespace());
        Name baseName = parser.parse(userBase);
        Name entryName = parser.parse(result.getName());
        Name name = contextName.addAll(baseName);
        name = name.addAll(entryName);
        String dn = name.toString();

        if (getLogger().isDebugEnabled())
            log("  entry found for " + username + " with dn " + dn);

        // Get the entry's attributes
        Attributes attrs = result.getAttributes();
        if (attrs == null)
            return null;

        return createUser(username, dn, attrs);
    }


    private JNDIUser createUser(String username, String dn, Attributes attrs) throws NamingException {
        // Retrieve value of userPassword
        String password = null;
        if (userPassword != null)
            password = getAttributeValue(userPassword, attrs);
        
        String mail = null;
        if ( userMail != null) {
            mail = getAttributeValue( userMail, attrs );
        }
        
        String cn = null;
        if ( userCn != null ) {
            cn = getAttributeValue( userCn, attrs );
        }
        return new JNDIUser(username, dn, password, mail, cn);
    }



    /**
     * Check whether the given User can be authenticated with the
     * given credentials. If the <code>userPassword</code>
     * configuration attribute is specified, the credentials
     * previously retrieved from the directory are compared explicitly
     * with those presented by the user. Otherwise the presented
     * credentials are checked by binding to the directory as the
     * user.
     *
     * @param context The directory context
     * @param user The User to be authenticated
     * @param credentials The credentials presented by the user
     *
     * @exception NamingException if a directory server error occurs
     */
    protected boolean checkCredentials(DirContext context,
                                     JNDIUser user,
                                     String credentials)
         throws NamingException {

         boolean validated = false;

         if (userPassword == null) {
             validated = bindAsUser(context, user, credentials);
         } else {
             validated = compareCredentials(context, user, credentials);
         }

         if ( getLogger().isDebugEnabled() ) {
             if (validated) {
                 log("jndiRealm.authenticateSuccess: " + user.username);
             } else {
                 log("jndiRealm.authenticateFailure: " + user.username);
             }
         }
         return (validated);
     }



    /**
     * Check whether the credentials presented by the user match those
     * retrieved from the directory.
     *
     * @param context The directory context
     * @param info The User to be authenticated
     * @param credentials Authentication credentials

⌨️ 快捷键说明

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