spring security源代码疑问

原文地址:

http://www.codes51.com/itwd/1474556.html



问题:spring security源代码疑问
描述:

项目里要使用spring security,
在使用的时候偶然读到了一段代码,没看懂。

就是下面这个方法,里面有个try catch。
catch了UsernameNotFoundException异常,
然后在异常处理中,验证密码了。
请问为什么用户已经确认不存在了,还要验证密码?

这段代码写在 
org.springframework.security.authentication.dao.DaoAuthenticationProvider

protected final UserDetails retrieveUser(String username,
            UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
        UserDetails loadedUser;

        try {
            loadedUser = this.getUserDetailsService().loadUserByUsername(username);
        }
        catch (UsernameNotFoundException notFound) {
            //这里为什么还要验证密码,用户不存在,验证密码意义何在?
            if (authentication.getCredentials() != null) {
                String presentedPassword = authentication.getCredentials().toString();
                passwordEncoder.isPasswordValid(userNotFoundEncodedPassword,
                        presentedPassword, null);
            }
            throw notFound;
        }
        catch (Exception repositoryProblem) {
            throw new InternalAuthenticationServiceException(
                    repositoryProblem.getMessage(), repositoryProblem);
        }

        if (loadedUser == null) {
            throw new InternalAuthenticationServiceException(
                    "UserDetailsService returned null, which is an interface contract violation");
        }
        return loadedUser;
    }

解决方案1:

spring security 4.0版 里面已经取消了

解决方案2:

我一初中同学微信昵称也是黑不溜秋, 不会是你吧?哈哈~

解决方案3:

/**

  • The password used to perform

  • {@link PasswordEncoder#isPasswordValid(String, String, Object)} on when the user is

  • not found to avoid SEC-2056. This is necessary, because some

  • {@link PasswordEncoder} implementations will short circuit if the password is not

  • in a valid format.
    */

不是描述得清清楚楚的么,不这样做会有bug :)

解决方案4:

下面这段话摘自SEC-2056的更新记录,这段话解释了为什么要加上这个检查:

Previously authenticating a user could take significantly longer than
determining that a user does not exist. This was due to the fact that only
users that were found would use the password encoder and comparing a
password can take a significant amount of time. The difference in the
time required could allow a side channel attack that reveals if a user
exists.

简单来说就是:在以前(本次更新前),一次用户认证花费的时间要比检查一个不存在的用户所花费的时间长不少,因为以前的做法是当用户不存在时就会跳过密码比较,因此省了很多时间。

这种做法会让攻击者能够通过认证过程所花费的时间长短来间接得知一个用户是否存在,这会带来安全隐患。

比如一个黑客想攻击系统,非法取得某个用户的身份。那么他首先要确定一个用户是否存在,然后再想办法破解该用户的密码。

在以前,黑客可以构造大量的用户名,每个用户随便使用一个密码,提交给系统去认证,这样他可以根据每次用户认证所花费的时间来得知某个用户是否存在。这样他就能在短时间内收集大量已存在的用户,接下来再进行密码破解即可。

而修改之后黑客就没办法这么干了,他无法轻易得到用户是否存在的信息,因此破解密码的成本会增加N倍——也许努力了半天只是在对一个不存在的用户进行破解,而这是毫无意义的!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值