アカウントロック機能の調査

 

这两天在调查“ 输错 n 次后 账户” 的功 ,日方客户想这样实现。

 

我先看文档,没找到相关内容。转变思路,在 IM 画面中查找,找到了很类似的功能,具体 情况是: IM 画面中提供的是 这样 的功能:用 户输错 的次数,会被自 动递 记录 帐户 管理 面(注意:假 设该 后来又正确登 了一下, 前面的 错误 次数会被清零),管理 可以据此决定是否 帐户

 

只要管理 员锁 定了某 帐户 即使以正确的用 / 码尝试 ,也无法 入, 面提示: 该帐户 已被 定,需要 系管理 员进 行解

 

但是,这个调查结果并不完全符合用户的需求,客户想要实现的是设置个数字,当最终用户输入密码错误次数达到这个数字时,就自动锁定该帐户,而不是让客户这个管理员自己去一个个地看,不是人为去锁定(解锁要求是人为解锁)。

 

 

没办法,还要继续。

 

今天上午一过来,尝试从新的思路入手。

 

调查用户登录时的处理逻辑,最终在开发环境的实例项目的 web.xml 文件中找到我想要的配置项:

    <servlet-mapping>

        <servlet-name>UserCertificationServlet</servlet-name>

         <url-pattern>/user.login</url-pattern>

    </servlet-mapping> 
 

根据这个找到对应的 Servlet

    <servlet>

        <servlet-name>UserCertificationServlet</servlet-name>

     <servlet-class>jp.co.intra_mart.foundation.security.servlet.UserCertificationServlet</servlet-class>

    </servlet> 

 

这个 servlet 是位于 IM jar 包中的,反编译,看源代码。

 

想到新的思路,修改此处配置:

    <servlet>

        <servlet-name>UserCertificationServlet</servlet-name>

                                <servlet-class>employee.password.UserCertificationServlet</servlet-class>

    </servlet> 
 

让用户登录时的处理逻辑不再指向原先 jar 包中的 servlet ,而是指向我的 servlet

 

我将原先的 UserCertificationServlet 拷贝过来,设置断点,不断地跑页面登录,将这段逻辑大概搞清楚后,然后加上自己的处理逻辑,主要就是用户登录错误此时达到或者超过设置的数字时,则将该用户锁定,需要管理员解锁。

 

经过 N 次尝试,经过 N-1 次失败,最终将其搞定了。

 

我追加的主要一段逻辑代码如下:

if  ( "user" .equals(loginInfo.getLoginType())) {

 

       AccountManager accountManager = new AccountManager(loginInfo.getLoginGroup());

       Account account = accountManager.getAccount(loginInfo.getUser());

                          

       String strLockCount = PropertiesUtil.getMessage ( "lockCount" );

       int intLockCount = 0;

       if (strLockCount != null && ! "" .equals(strLockCount.trim())) {

                     intLockCount = Integer.parseInt (strLockCount);

       }

 

                           // このユーザのログイン失敗回数 >=ロック設定回数

            if (account != null && account.getLoginFailureCount() >= intLockCount) {

 

                                  // 日付を設定した場合、アカウントはロックされる。

                                  account.setLockDate(new Date());

                                  // アカウントを更新します。

                                  accountManager.updateAccount(account);

                                  // ロックフラッグ

                                  loginCertification = -3;

              }

       } 

 

分析: debug 发现,源代码中, loginCertification 3时表示登录成功,为 0时表示登录失败,为 -3时表示帐户已被锁定。

 

引入的两个包主要是:

import  jp.co.intra_mart.foundation.security.account.Account;

import jp.co.intra_mart.foundation.security.account.AccountManager; 
   

其中,关键的两点就是:

account.setLockDate(new Date()); accountManager.updateAccount(account);

前者主要是利用现在的时间作为参数传进去将帐户 account 锁定(意思就是立即锁定该帐户);

后者主要是将对该帐户的锁定信息更新一下(特别注意后面这一点,只有 update 后才会在 group 管理界面上真正自动将该用户锁定)。

 

我将以前写过的配置文件处理类拷贝过来,这样,最终实现了客户的需求:在 properties属性文件中进行设置,当最终用户登录次数达到或者超过这个数字时,就会自动将这个帐户锁定,需要管理员进行解锁操作。

 

但是,我自己也小结了下: 可能也可以使用 Listeren 来实现,但是昨天下午也大概看过这方面的 API ,没看到什么对应的方法,也没什么思路。

 

感觉现在的这种实现还是有点隐患的: 原先用 group )都是交 jp.co.intra_mart.foundation.security.servlet.UserCertificationServlet 的, 实现对 户帐户进 定, 修改了 web.xml 中配置 UserCertificationServlet 的指向 Servlet 文件。

尽管个人已 经进 行了多次 测试 ,但 是有点担心

 

 

 

20090123追加:

 

部门首席技术专家改进本例,使用了Filter,学习一下。

 

总体概述:

 

写了一个过滤器来达到指定类型的用户在登录失败次数到达指定数值时,锁定该用户。

/user.login 这个页面是由Servlet:UserCertificationServlet? (jp.co.intra_mart.foundation.security.servlet.UserCertificationServlet? ) 处理的,给它加一个Filter,使得在servlet执行完成后追加执行失败次数检查,一旦满足条件(用户类型满足设定的类型,该用户当前尚未被锁定 且,该用户的登录失败次数超过指定的最大次数)就将该用户的锁定日期设置为当前日期。用户即被锁定,该用户再尝试登录将得到错误提示:

指定されたアカウントはロックされているためログインできませんでした。
しばらくたってから再ログインして下さい。

 

web.xml中的对应配置:

    <!-- アカウントロック -->
    <filter>
        <filter-name>LoginFailureCountCheckFilter</filter-name>
        <filter-class>**.**.LoginFailureCountCheckFilter</filter-class>
        <init-param>
            <description>The login type of the user that to check.</description>
            <param-name>loginType</param-name>
            <param-value>user</param-value>
        </init-param>
        <init-param>
            <description>The maximum allowable login failure count.</description>
            <param-name>maxFailureCount</param-name>
            <param-value>2</param-value>
        </init-param>
    </filter>
    
    
    
   <!-- アカウントロック -->
    <filter-mapping>
        <filter-name>LoginFailureCountCheckFilter</filter-name>
        <servlet-name>UserCertificationServlet</servlet-name>
    </filter-mapping>
	
	
	<servlet>
        <servlet-name>UserCertificationServlet</servlet-name>
        <servlet-class>jp.co.intra_mart.foundation.security.servlet.UserCertificationServlet</servlet-class>
    </servlet>
	
	
	<servlet-mapping>
        <servlet-name>UserCertificationServlet</servlet-name>
        <url-pattern>/user.login</url-pattern>
    </servlet-mapping>
 

 

Filter处理类LoginFailureCountCheckFilter.java

/**
 * 
 */
package ***.***.web.filter;

import java.io.IOException;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import jp.co.intra_mart.common.platform.log.Logger;
import jp.co.intra_mart.foundation.security.account.Account;
import jp.co.intra_mart.foundation.security.account.AccountManager;
import jp.co.intra_mart.foundation.security.certification.LoginRequestInfo;
import jp.co.intra_mart.foundation.security.exception.AccessSecurityException;
import jp.co.intra_mart.system.security.LoginInfoSerializer;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

/**
 * アカウントロック。
 * 
 * @author **, **
 */
public class LoginFailureCountCheckFilter implements Filter {
    private static final Logger LOG = Logger.getLogger(LoginFailureCountCheckFilter.class);
    private static final boolean DEBUG = LOG.isDebugEnabled();

    /**
     * The login type of the user that to check.
     */
    private String loginType;

    /**
     * The maximum allowable login failure count.
     */
    private int maxFailureCount;

    /**
     * {@inheritDoc}
     */
    public void init(FilterConfig config) throws ServletException {
        this.maxFailureCount = NumberUtils.toInt(config.getInitParameter("maxFailureCount"));
        this.loginType = StringUtils.trim(config.getInitParameter("loginType"));
    }

    /**
     * {@inheritDoc}
     */
    public void destroy() {
    }

    /**
     * {@inheritDoc}
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException,
            IOException {
        // Execute the servlet "jp.co.intra_mart.foundation.security.servlet.UserCertificationServlet" first,
        // as it increase the failure count while login failure.
        chain.doFilter(request, response);

        // Check failure count.
        doCheck(request, response);
    }

    /**
     * Do check failure count.
     * 
     * @param request
     *            the servlet request
     * @param response
     *            the servlet response
     */
    private void doCheck(ServletRequest request, ServletResponse response) {
        String imLoginInfo = request.getParameter("im_login_info");
        String username = request.getParameter("im_user");

        LoginRequestInfo loginInfo = LoginInfoSerializer.load(imLoginInfo);

        try {
            checkFailureCount(loginInfo, username);
        } catch (AccessSecurityException e) {
            LOG.error(e.getMessage(), e);
        }
    }

    /**
     * Check the failure count of <code>loginInfo</code>, if it max than
     * {@link #maxFailureCount}, lock the user.
     * 
     * @param loginInfo
     *            the login info
     * @param username
     *            the username
     * @throws AccessSecurityException
     *             if access the account manager failed
     */
    private void checkFailureCount(LoginRequestInfo loginInfo, String username) throws AccessSecurityException {
        if (StringUtils.equals(this.loginType, loginInfo.getLoginType())) {
            AccountManager accountManager = new AccountManager(loginInfo.getLoginGroup());
            Account account = accountManager.getAccount(username);

            if (DEBUG) {
                LOG.debug("The login failure count of user {} is {}.", account.getUserId(), account
                        .getLoginFailureCount());
            }
            // このユーザのログイン失敗回数>=ロック設定回数
            if (account != null && !account.isLock() && account.getLoginFailureCount() > this.maxFailureCount) {
                if (DEBUG) {
                    LOG.debug("Locking user {}as the login failure count {} is greater than the max failure count {}.",
                            account.getUserId(), account.getLoginFailureCount(), this.maxFailureCount);
                }
                // 日付を設定した場合、アカウントはロックされる。
                account.setLockDate(new Date());
                // アカウントを更新します。
                accountManager.updateAccount(account);
            }
        }
    }

}
 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 1. 首先,下载并安装VMware Workstation 16 Pro安装程序。 2. 打开安装程序,选择“安装”选项。 3. 阅读并接受许可协议。 4. 选择安装类型,可以选择默认安装或自定义安装。 5. 如果选择自定义安装,可以选择安装位置和其他选项。 6. 点击“安装”按钮开始安装。 7. 安装完成后,启动VMware Workstation 16 Pro。 8. 创建一个新的虚拟机或打开现有的虚拟机。 9. 配置虚拟机的设置,包括操作系统、硬件配置和网络设置等。 10. 启动虚拟机并开始使用。 ### 回答2: vmware workstation16 pro是一款功能丰富的虚拟机软件,可以在一台主机上创建多个虚拟机实例。以下是安装教程: 1.首先,下载安装文件。可以从官网或其他下载网站下载。 2.运行安装程序。在安装程序窗口中,单击“下一步”按钮,就可以进入下一步。 3.阅读许可协议并接受。勾选“我接受许可协议”并单击“下一步”按钮。 4.选择要安装的组件。您可以选择将软件安装到哪个位置以及是否创建快捷方式。 (建议保持默认设置) 5.配置网络类型。默认情况下,vmware workstation会使用桥接模式,这将使您的虚拟机拥有独立的IP地址。如果需要更改,可以手动更改网络配置。 6.输入序列号。如果您没有购买软件,则可以选择“30天试用版”,但需要输入您的电子邮件地址。 7.单击“安装”按钮。安装过程可能需要数分钟,根据您的计算机配置和软件版本而有所不同。 8.完成安装。单击“完成”按钮,您就可以开始使用vmware workstation16 pro了! 总体来说,vmware workstation16 pro是一款强大的虚拟机软件,可以为用户提供完美的虚拟化体验。安装过程简单易操作,用户可以很快掌握。此外,该软件还提供了许多功能和选项,例如虚拟网络设置、虚拟机快照等,方便用户进行虚拟化管理和操作。 ### 回答3: VMware Workstation是一款非常流行的虚拟机软件,它可以在一台物理计算机中运行多个不同的操作系统(例如Windows、Linux、Mac OS等),这些操作系统可以独立运行,互不干扰。VMware Workstation 16 ProVMware最新推出的版本,其安装方法如下: 1. 下载安装文件。首先,需要从VMware官网下载VMware Workstation 16 Pro的安装文件。文件下载完成后,可以双击打开安装程序。 2. 启动安装程序。在安装程序启动后,系统会提示是否接受许可协议。如果同意,请勾选“我接受许可协议”的选项,然后点击“下一步”。 3. 选择安装方式。根据不同的需求选择合适的安装方式。在标准安装中,VMware Workstation 16 Pro将被安装在默认路径下。自定义安装可选择安装路径,也可选择不安装某些组件,如USB控制器、音频设备等。 4. 输入序列号。需要输入序列号来激活VMware Workstation 16 Pro。如果没有序列号,请选择“使用30天试用版本”选项。 5. 安装过程。接下来,安装程序会开始安装VMware Workstation 16 Pro。在安装过程中,可以选择是否启用共享文件夹、网络适配器等选项。 6. 安装完成。安装过程完成后,点击“完成”按钮退出安装程序。此时,可以在桌面或应用程序列表中找到VMware Workstation 16 Pro的图标。 7. 启动VMware Workstation 16 Pro。双击图标启动VMware Workstation 16 Pro,然后可以开始创建虚拟机、导入虚拟机等操作。 总而言之,VMware Workstation 16 Pro是一款功能强大的虚拟机软件,其安装过程简单易懂,只需要按照步骤逐一执行即可。使用VMware Workstation 16 Pro,可以轻松创建多个操作系统实例,实现多操作系统并行运行,提高工作效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值