ApacheFTPServer结合数据库管理用户(二)

ApacheFTPServer利用数据库进行用户管理

1、引入数据库驱动

本文用MySQL举例,JDK1.8版本。

#查看数据库的版本,根据版本导入对应的数据库驱动版本
SELECT VERSION();

版本之间的对应参照。官网文档: https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-versions.html
ApacheFTPServer结合数据库管理用户(二)_第1张图片
我的MySQL版本为8.0.12,导入的版本为8.0.19。

		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

编写测试类,测试连接。(连接参数记得修改)

public static void main(String[] args) {
        String url="jdbc:mysql://192.168.1.122:3306/mysql?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false";
        String user="root";
        String password="12345";
        try {
            //1. 加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2. 获取连接
            Connection conn= DriverManager.getConnection(url,user,password);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        System.out.println("连接成功");
    }

2、FTP服务结合数据库管理用户

数据库创建用户表

CREATE TABLE FTP_USER (
  userid VARCHAR (64) NOT NULL PRIMARY KEY COMMENT '登入账号',
  userpassword VARCHAR (64) COMMENT '登入密码',
  homedirectory VARCHAR (128) NOT NULL COMMENT '主目录',
  enableflag BOOLEAN DEFAULT TRUE COMMENT '用户是否可用',
  writepermission BOOLEAN DEFAULT FALSE COMMENT '是否拥有写权限',
  idletime INT DEFAULT 0 COMMENT '空闲时间(s)',
  uploadrate INT DEFAULT 0 COMMENT '上传速度(byte)',
  downloadrate INT DEFAULT 0 COMMENT '下载速度(byte)',
  maxloginnumber INT DEFAULT 0 COMMENT '最大登录数',
  maxloginperip INT DEFAULT 0 COMMENT '最大登录数同IP'
);
#插入用户 admin admin,根目录C盘用户文件夹(1表示true)
INSERT INTO FTP_USER 
VALUES
  (
    "admin",
    "admin",
    "C:\Users",
    1,
    1,
    60,
    10240,
    10240,
    1,
    1
  );

3、启动FTP服务

package apache.ftp.server.test;

import com.mysql.cj.jdbc.MysqlDataSource;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.usermanager.DbUserManagerFactory;
import org.apache.ftpserver.usermanager.PasswordEncryptor;

public class FtpServerApplication {
    public static void main(String[] args) throws Exception {
        FtpServerFactory serverFactory = new FtpServerFactory();

        //Factory for database
        DbUserManagerFactory dbUserManagerFactory = new DbUserManagerFactory();
        dbUserManagerFactory.setSqlUserAdmin("SELECT userid FROM FTP_USER WHERE userid='admin'");
        dbUserManagerFactory.setSqlUserAuthenticate("SELECT userpassword FROM FTP_USER WHERE userid='{userid}'");
        dbUserManagerFactory.setSqlUserDelete("DELETE FROM FTP_USER WHERE userid='{userid}'");
        dbUserManagerFactory.setSqlUserInsert("INSERT INTO FTP_USER('userid', 'userpassword', 'enableflag', 'homedirectory', 'writepermission', 'idletime', 'uploadrate', 'downloadrate') VALUES ('{userid}', '{userpassword}',{enableflag},'{homedirectory}', {writepermission},{idletime},{uploadrate},{downloadrate})");
        dbUserManagerFactory.setSqlUserUpdate("UPDATE FTP_USER SET userpassword='{userpassword}',homedirectory='{homedirectory}',enableflag={enableflag},writepermission={writepermission},idletime={idletime},uploadrate={uploadrate},downloadrate={downloadrate} WHERE userid='{userid}'");
        dbUserManagerFactory.setSqlUserSelect("SELECT userid, userpassword, homedirectory, enableflag, writepermission, idletime, uploadrate,downloadrate,maxloginnumber, maxloginperip FROM FTP_USER WHERE userid = '{userid}'");
        dbUserManagerFactory.setSqlUserSelectAll("SELECT userid FROM FTP_USER ORDER BY userid");
        dbUserManagerFactory.setPasswordEncryptor(new PasswordEncryptor() {
            //We store clear-text passwords in this example
            @Override
            public String encrypt(String password) {
                return password;
            }

            @Override
            public boolean matches(String passwordToCheck, String storedPassword) {
                return passwordToCheck.equals(storedPassword);
            }
        });
        //记得修改数据库地址
        String url = "jdbc:mysql://192.168.1.122:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false";
        String user = "root";
        String password = "12345";
        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setURL(url);
        dataSource.setUser(user);
        dataSource.setPassword(password);
        //Set the data source to be used by the user manager
        dbUserManagerFactory.setDataSource(dataSource);

        serverFactory.setUserManager(dbUserManagerFactory.createUserManager());

        //Your FTP server starts listening for incoming FTP-connections, using the configuration options previously set
        FtpServer server = serverFactory.createServer();
        server.start();
    }
}

4、测试连接

C:\Users\admin>ftp
ftp> open 127.0.0.1
连接到 127.0.0.1。
220 Service ready for new user.
530 Access denied.
用户(127.0.0.1:(none)): admin
331 User name okay, need password for admin.
密码:
230 User logged in, proceed.
ftp> ls
200 Command PORT okay.
150 File status okay; about to open data connection.
Public
admin
226 Closing data connection.
ftp: 收到 18 字节,用时 0.00秒 9.00千字节/秒。
ftp>

测试完成,代码只是用户测试,如要运用到实际项目中,还有很多路要走。

5、用户管理的实现源码

不才,如有不足错误之处,还望评论区指教。

package org.apache.ftpserver.ftplet;
/**
 * Apache 定义了用户管理的接口,只要我们实现了该接口,用户数据放哪都可以。
 */
public interface UserManager {
    User getUserByName(String username) throws FtpException;

    String[] getAllUserNames() throws FtpException;
    
    void delete(String username) throws FtpException;

    void save(User user) throws FtpException;

    boolean doesExist(String username) throws FtpException;

    User authenticate(Authentication authentication)throws AuthenticationFailedException;
            
    String getAdminName() throws FtpException;

    boolean isAdmin(String username) throws FtpException;
}

package org.apache.ftpserver.usermanager.impl;

import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.usermanager.Md5PasswordEncryptor;
import org.apache.ftpserver.usermanager.PasswordEncryptor;

/**
 * 就是根据这个抽象类来创建我们的数据表结构的。主要用于子类继承夫,复用父类的常量
 */
public abstract class AbstractUserManager implements UserManager {

    public static final String ATTR_LOGIN = "userid";

    public static final String ATTR_PASSWORD = "userpassword";

    public static final String ATTR_HOME = "homedirectory";

    public static final String ATTR_WRITE_PERM = "writepermission";

    public static final String ATTR_ENABLE = "enableflag";

    public static final String ATTR_MAX_IDLE_TIME = "idletime";

    public static final String ATTR_MAX_UPLOAD_RATE = "uploadrate";

    public static final String ATTR_MAX_DOWNLOAD_RATE = "downloadrate";

    public static final String ATTR_MAX_LOGIN_NUMBER = "maxloginnumber";

    public static final String ATTR_MAX_LOGIN_PER_IP = "maxloginperip";

    private final String adminName;
    
    private final PasswordEncryptor passwordEncryptor;

    public AbstractUserManager() {
        this(null,  new Md5PasswordEncryptor());
    }
    
    public AbstractUserManager(String adminName, PasswordEncryptor passwordEncryptor) {
        this.adminName = adminName;
        this.passwordEncryptor = passwordEncryptor;
    }
    
    public String getAdminName() {
        return adminName;
    }

    public boolean isAdmin(String login) throws FtpException {
        return adminName.equals(login);
    }

    public PasswordEncryptor getPasswordEncryptor() {
        return passwordEncryptor;
    }
}

package org.apache.ftpserver.usermanager.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.sql.DataSource;

import org.apache.ftpserver.FtpServerConfigurationException;
import org.apache.ftpserver.ftplet.Authentication;
import org.apache.ftpserver.ftplet.AuthenticationFailedException;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.User;
import org.apache.ftpserver.usermanager.AnonymousAuthentication;
import org.apache.ftpserver.usermanager.DbUserManagerFactory;
import org.apache.ftpserver.usermanager.PasswordEncryptor;
import org.apache.ftpserver.usermanager.UsernamePasswordAuthentication;
import org.apache.ftpserver.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 数据库用户管理主要实现类,定义了SQL,获取连接执行SQL,复用父类的字段变量,进行读取
 */
public class DbUserManager extends AbstractUserManager {

    private final Logger LOG = LoggerFactory.getLogger(DbUserManager.class);

    private String insertUserStmt;

    private String updateUserStmt;

    private String deleteUserStmt;

    private String selectUserStmt;

    private String selectAllStmt;

    private String isAdminStmt;

    private String authenticateStmt;

    private DataSource dataSource;

    public DbUserManager(DataSource dataSource, String selectAllStmt,
            String selectUserStmt, String insertUserStmt,
            String updateUserStmt, String deleteUserStmt,
            String authenticateStmt, String isAdminStmt,
            PasswordEncryptor passwordEncryptor, String adminName) {
        super(adminName, passwordEncryptor);
        this.dataSource = dataSource;
        this.selectAllStmt = selectAllStmt;
        this.selectUserStmt = selectUserStmt;
        this.insertUserStmt = insertUserStmt;
        this.updateUserStmt = updateUserStmt;
        this.deleteUserStmt = deleteUserStmt;
        this.authenticateStmt = authenticateStmt;
        this.isAdminStmt = isAdminStmt;

        Connection con = null; 
        try { 
                // test the connection 
                con = createConnection(); 
                
                LOG.info("Database connection opened."); 
        } catch (SQLException ex) { 
                LOG.error("Failed to open connection to user database", ex); 
                throw new FtpServerConfigurationException( 
                "Failed to open connection to user database", ex); 
        } finally{ 
                closeQuitely(con); 
        }
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }


    public String getSqlUserInsert() {
        return insertUserStmt;
    }

    public void setSqlUserInsert(String sql) {
        insertUserStmt = sql;
    }

    public String getSqlUserDelete() {
        return deleteUserStmt;
    }

    public void setSqlUserDelete(String sql) {
        deleteUserStmt = sql;
    }

    public String getSqlUserUpdate() {
        return updateUserStmt;
    }
    
    public void setSqlUserUpdate(String sql) {
        updateUserStmt = sql;
    }
    
    public String getSqlUserSelect() {
        return selectUserStmt;
    }
    
    public void setSqlUserSelect(String sql) {
        selectUserStmt = sql;
    }

    public String getSqlUserSelectAll() {
        return selectAllStmt;
    }
    
    public void setSqlUserSelectAll(String sql) {
        selectAllStmt = sql;
    }

    public String getSqlUserAuthenticate() {
        return authenticateStmt;
    }

    public void setSqlUserAuthenticate(String sql) {
        authenticateStmt = sql;
    }

    public String getSqlUserAdmin() {
        return isAdminStmt;
    }

    public void setSqlUserAdmin(String sql) {
        isAdminStmt = sql;
    }

    @Override
    public boolean isAdmin(String login) throws FtpException {

        // check input
        if (login == null) {
            return false;
        }

        Statement stmt = null;
        ResultSet rs = null;
        try {

            // create the sql query
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put(ATTR_LOGIN, escapeString(login));
            String sql = StringUtils.replaceString(isAdminStmt, map);
            LOG.info(sql);

            // execute query
            stmt = createConnection().createStatement();
            rs = stmt.executeQuery(sql);
            return rs.next();
        } catch (SQLException ex) {
            LOG.error("DbUserManager.isAdmin()", ex);
            throw new FtpException("DbUserManager.isAdmin()", ex);
        } finally {
            closeQuitely(rs);
            closeQuitely(stmt);
        }
    }

    /**
     * Open connection to database.
     */
    protected Connection createConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        connection.setAutoCommit(true);

        return connection;
    }


    /**
     * Delete user. Delete the row from the table.
     */
    public void delete(String name) throws FtpException {
        // create sql query
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put(ATTR_LOGIN, escapeString(name));
        String sql = StringUtils.replaceString(deleteUserStmt, map);
        LOG.info(sql);

        // execute query
        Statement stmt = null;
        try {
            stmt = createConnection().createStatement();
            stmt.executeUpdate(sql);
        } catch (SQLException ex) {
            LOG.error("DbUserManager.delete()", ex);
            throw new FtpException("DbUserManager.delete()", ex);
        } finally {
            closeQuitely(stmt);
        }
    }

    /**
     * Save user. If new insert a new row, else update the existing row.
     */
    public void save(User user) throws FtpException {
        // null value check
        if (user.getName() == null) {
            throw new NullPointerException("User name is null.");
        }

        Statement stmt = null;
        try {

            // create sql query
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put(ATTR_LOGIN, escapeString(user.getName()));

            String password = null;
            if(user.getPassword() != null) {
                // password provided, encrypt it and store the encrypted value
                password= getPasswordEncryptor().encrypt(user.getPassword());
            } else {
                // password was not provided, either load from the existing user and store that again
                // or store as null
                ResultSet rs = null;

                try {
                    User userWithPassword = selectUserByName(user.getName());

                    if(userWithPassword != null) {
                        // user exists, reuse password
                        password = userWithPassword.getPassword();
                    }
                } finally {
                    closeQuitely(rs);
                }
            }
            map.put(ATTR_PASSWORD, escapeString(password));


            String home = user.getHomeDirectory();
            if (home == null) {
                home = "/";
            }
            map.put(ATTR_HOME, escapeString(home));
            map.put(ATTR_ENABLE, String.valueOf(user.getEnabled()));

            map.put(ATTR_WRITE_PERM, String.valueOf(user
                    .authorize(new WriteRequest()) != null));
            map.put(ATTR_MAX_IDLE_TIME, user.getMaxIdleTime());

            TransferRateRequest transferRateRequest = new TransferRateRequest();
            transferRateRequest = (TransferRateRequest) user
                    .authorize(transferRateRequest);

            if (transferRateRequest != null) {
                map.put(ATTR_MAX_UPLOAD_RATE, transferRateRequest
                        .getMaxUploadRate());
                map.put(ATTR_MAX_DOWNLOAD_RATE, transferRateRequest
                        .getMaxDownloadRate());
            } else {
                map.put(ATTR_MAX_UPLOAD_RATE, 0);
                map.put(ATTR_MAX_DOWNLOAD_RATE, 0);
            }

            // request that always will succeed
            ConcurrentLoginRequest concurrentLoginRequest = new ConcurrentLoginRequest(
                    0, 0);
            concurrentLoginRequest = (ConcurrentLoginRequest) user
                    .authorize(concurrentLoginRequest);

            if (concurrentLoginRequest != null) {
                map.put(ATTR_MAX_LOGIN_NUMBER, concurrentLoginRequest
                        .getMaxConcurrentLogins());
                map.put(ATTR_MAX_LOGIN_PER_IP, concurrentLoginRequest
                        .getMaxConcurrentLoginsPerIP());
            } else {
                map.put(ATTR_MAX_LOGIN_NUMBER, 0);
                map.put(ATTR_MAX_LOGIN_PER_IP, 0);
            }

            String sql = null;
            if (!doesExist(user.getName())) {
                sql = StringUtils.replaceString(insertUserStmt, map);
            } else {
                sql = StringUtils.replaceString(updateUserStmt, map);
            }
            LOG.info(sql);

            // execute query
            stmt = createConnection().createStatement();
            stmt.executeUpdate(sql);
        } catch (SQLException ex) {
            LOG.error("DbUserManager.save()", ex);
            throw new FtpException("DbUserManager.save()", ex);
        } finally {
            closeQuitely(stmt);
        }
    }

    private void closeQuitely(Statement stmt) {
        if(stmt != null) {
	    Connection con = null;
	    try {
		con = stmt.getConnection();
	    } catch (Exception e) {
	    }
	    try {
                stmt.close();
            } catch (SQLException e) {
                // ignore
            }
	    closeQuitely(con);
        }
    }

    private void closeQuitely(ResultSet rs) {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // ignore
            }
        }
    }

    protected void closeQuitely(Connection con) {
	if (con != null) {
	    try {
		con.close();
	    } catch (SQLException e) {
		// ignore
	    }
	}
    }

    private BaseUser selectUserByName(String name) throws SQLException {
        // create sql query
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put(ATTR_LOGIN, escapeString(name));
        String sql = StringUtils.replaceString(selectUserStmt, map);
        LOG.info(sql);

        Statement stmt = null;
        ResultSet rs = null;
        try {
            // execute query
            stmt = createConnection().createStatement();
            rs = stmt.executeQuery(sql);

            // populate user object
            BaseUser thisUser = null;
            if (rs.next()) {
                thisUser = new BaseUser();
                thisUser.setName(rs.getString(ATTR_LOGIN));
                thisUser.setPassword(rs.getString(ATTR_PASSWORD));
                thisUser.setHomeDirectory(rs.getString(ATTR_HOME));
                thisUser.setEnabled(rs.getBoolean(ATTR_ENABLE));
                thisUser.setMaxIdleTime(rs.getInt(ATTR_MAX_IDLE_TIME));

                List<Authority> authorities = new ArrayList<Authority>();
                if (rs.getBoolean(ATTR_WRITE_PERM)) {
                    authorities.add(new WritePermission());
                }

                authorities.add(new ConcurrentLoginPermission(rs
                        .getInt(ATTR_MAX_LOGIN_NUMBER), rs
                        .getInt(ATTR_MAX_LOGIN_PER_IP)));
                authorities.add(new TransferRatePermission(rs
                        .getInt(ATTR_MAX_DOWNLOAD_RATE), rs
                        .getInt(ATTR_MAX_UPLOAD_RATE)));

                thisUser.setAuthorities(authorities);
            }
            return thisUser;

        } finally {
            closeQuitely(rs);
            closeQuitely(stmt);
        }
    }

    public User getUserByName(String name) throws FtpException {
        Statement stmt = null;
        ResultSet rs = null;
        try {

            BaseUser user = selectUserByName(name);

            if(user != null) {
                // reset the password, not to be sent to API users
                user.setPassword(null);
            }
            return user;


        } catch (SQLException ex) {
            LOG.error("DbUserManager.getUserByName()", ex);
            throw new FtpException("DbUserManager.getUserByName()", ex);
        } finally {
            closeQuitely(rs);
            closeQuitely(stmt);
        }
    }

    public boolean doesExist(String name) throws FtpException {
        Statement stmt = null;
        ResultSet rs = null;
        try {

            // create the sql
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put(ATTR_LOGIN, escapeString(name));
            String sql = StringUtils.replaceString(selectUserStmt, map);
            LOG.info(sql);

            // execute query
            stmt = createConnection().createStatement();
            rs = stmt.executeQuery(sql);
            return rs.next();
        } catch (SQLException ex) {
            LOG.error("DbUserManager.doesExist()", ex);
            throw new FtpException("DbUserManager.doesExist()", ex);
        } finally {
            closeQuitely(rs);
            closeQuitely(stmt);
        }
    }
    
    public String[] getAllUserNames() throws FtpException {

        Statement stmt = null;
        ResultSet rs = null;
        try {

            // create sql query
            String sql = selectAllStmt;
            LOG.info(sql);

            // execute query
            stmt = createConnection().createStatement();
            rs = stmt.executeQuery(sql);

            // populate list
            ArrayList<String> names = new ArrayList<String>();
            while (rs.next()) {
                names.add(rs.getString(ATTR_LOGIN));
            }
            return names.toArray(new String[0]);
        } catch (SQLException ex) {
            LOG.error("DbUserManager.getAllUserNames()", ex);
            throw new FtpException("DbUserManager.getAllUserNames()", ex);
        } finally {
            closeQuitely(rs);
            closeQuitely(stmt);
        }
    }

    public User authenticate(Authentication authentication)
            throws AuthenticationFailedException {
        if (authentication instanceof UsernamePasswordAuthentication) {
            UsernamePasswordAuthentication upauth = (UsernamePasswordAuthentication) authentication;

            String user = upauth.getUsername();
            String password = upauth.getPassword();

            if (user == null) {
                throw new AuthenticationFailedException("Authentication failed");
            }

            if (password == null) {
                password = "";
            }

            Statement stmt = null;
            ResultSet rs = null;
            try {

                // create the sql query
                HashMap<String, Object> map = new HashMap<String, Object>();
                map.put(ATTR_LOGIN, escapeString(user));
                String sql = StringUtils.replaceString(authenticateStmt, map);
                LOG.info(sql);

                // execute query
                stmt = createConnection().createStatement();
                rs = stmt.executeQuery(sql);
                if (rs.next()) {
                    try {
                        String storedPassword = rs.getString(ATTR_PASSWORD);
                        if (getPasswordEncryptor().matches(password, storedPassword)) {
                            return getUserByName(user);
                        } else {
                            throw new AuthenticationFailedException(
                                    "Authentication failed");
                        }
                    } catch (FtpException e) {
                        throw new AuthenticationFailedException(
                                "Authentication failed", e);
                    }
                } else {
                    throw new AuthenticationFailedException(
                            "Authentication failed");
                }
            } catch (SQLException ex) {
                LOG.error("DbUserManager.authenticate()", ex);
                throw new AuthenticationFailedException(
                        "Authentication failed", ex);
            } finally {
                closeQuitely(rs);
                closeQuitely(stmt);
            }
        } else if (authentication instanceof AnonymousAuthentication) {
            try {
                if (doesExist("anonymous")) {
                    return getUserByName("anonymous");
                } else {
                    throw new AuthenticationFailedException(
                            "Authentication failed");
                }
            } catch (AuthenticationFailedException e) {
                throw e;
            } catch (FtpException e) {
                throw new AuthenticationFailedException(
                        "Authentication failed", e);
            }
        } else {
            throw new IllegalArgumentException(
                    "Authentication not supported by this user manager");
        }
    }

    private String escapeString(String input) {
        if (input == null) {
            return input;
        }

        StringBuilder valBuf = new StringBuilder(input);
        for (int i = 0; i < valBuf.length(); i++) {
            char ch = valBuf.charAt(i);
            if (ch == '\'' || ch == '\\' || ch == '$' || ch == '^' || ch == '['
                    || ch == ']' || ch == '{' || ch == '}') {

                valBuf.insert(i, '\\');
                i++;
            }
        }
        return valBuf.toString();
    }
}
package org.apache.ftpserver.ftplet;

import java.util.List;

/**
 * 正如我们开发过程中,需要创建实体类来接收数据库的数据,这里定义了用户对象主要实现的接口
 * 可以借鉴其数据设计思想,应用到今后的开发过程中
 */
public interface User {

    String getName();
    
    String getPassword();
    
    List<? extends Authority> getAuthorities();

    List<? extends Authority> getAuthorities(Class<? extends Authority> clazz);

    AuthorizationRequest authorize(AuthorizationRequest request);

    int getMaxIdleTime();
    
    boolean getEnabled();

    String getHomeDirectory();
}
package org.apache.ftpserver.usermanager.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.AuthorizationRequest;
import org.apache.ftpserver.ftplet.User;

/**
 * 这就是实际所用到的用户对象,包含了所需要的用户信息
 * 在DbUserManager类selectUserByName方法中实现装载
 */
public class BaseUser implements User {

    private String name = null;

    private String password = null;

    private int maxIdleTimeSec = 0; // no limit

    private String homeDir = null;

    private boolean isEnabled = true;

    private List<? extends Authority> authorities = new ArrayList<Authority>();

    public BaseUser() {
    }

    public BaseUser(User user) {
        name = user.getName();
        password = user.getPassword();
        authorities = user.getAuthorities();
        maxIdleTimeSec = user.getMaxIdleTime();
        homeDir = user.getHomeDirectory();
        isEnabled = user.getEnabled();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String pass) {
        password = pass;
    }

    public List<Authority> getAuthorities() {
        if (authorities != null) {
            return Collections.unmodifiableList(authorities);
        } else {
            return null;
        }
    }

    public void setAuthorities(List<Authority> authorities) {
        if (authorities != null) {
            this.authorities = Collections.unmodifiableList(authorities);
        } else {
            this.authorities = null;
        }
    }

    public int getMaxIdleTime() {
        return maxIdleTimeSec;
    }
    
    public void setMaxIdleTime(int idleSec) {
        maxIdleTimeSec = idleSec;
        if (maxIdleTimeSec < 0) {
            maxIdleTimeSec = 0;
        }
    }

    public boolean getEnabled() {
        return isEnabled;
    }

    public void setEnabled(boolean enb) {
        isEnabled = enb;
    }
    
    public String getHomeDirectory() {
        return homeDir;
    }

    public void setHomeDirectory(String home) {
        homeDir = home;
    }
    
    @Override
    public String toString() {
        return name;
    }
    
    public AuthorizationRequest authorize(AuthorizationRequest request) {
        // check for no authorities at all
        if(authorities == null) {
            return null;
        }
        
        boolean someoneCouldAuthorize = false;
        for (Authority authority : authorities) {
            if (authority.canAuthorize(request)) {
                someoneCouldAuthorize = true;

                request = authority.authorize(request);

                // authorization failed, return null
                if (request == null) {
                    return null;
                }
            }

        }

        if (someoneCouldAuthorize) {
            return request;
        } else {
            return null;
        }
    }

    public List<Authority> getAuthorities(Class<? extends Authority> clazz) {
        List<Authority> selected = new ArrayList<Authority>();

        for (Authority authority : authorities) {
            if (authority.getClass().equals(clazz)) {
                selected.add(authority);
            }
        }

        return selected;
    }
}

过程大概就是这样,通过工厂类DbUserManagerFactory创建DbUserManager,在DbUserManager中定义了数据库连接,还有SQL,实现了数据库的用户管理。用于装载用户信息的是BaseUser,可以在DbUserManager的selectUserByName方法中获取当前用户信息。登录成功后,将BaseUser放到session中,在执行命令需求时取出判断。

如果我们的用户数据放在Redis中,我们就可以创建一个RedisUserManagerFactory来创建RedisUserManager,其中定义Redis的连接和命令字符串,实现Redis的用户管理。自定义RedisUser实现User,增加我们业务需求的字段。

你可能感兴趣的:(JAVA,ApacheFTPServer)