spring-security - spring security源代码疑问

查看:184
本文介绍了spring-security - 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;
    }

解决方案

下面这段话摘自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倍——也许努力了半天只是在对一个不存在的用户进行破解,而这是毫无意义的!

这篇关于spring-security - spring security源代码疑问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆