当前位置: 首页 > 面试题库 >

Spring Security:抛出LockedException而不是BadCredentialsException,为什么?

淳于俊迈
2023-03-14
问题内容

使用Spring Security 4.0.2.RELEASE

对于使用spring-security框架的基本用户身份验证,我实现了spring-security DaoAuthenticationProvider

当用户尝试使用正确的用户名登录时, 错误的 密码和用户的 帐户已经被锁定 ,那么我希望spring-
security身份验证模块会抛出BadCredentialsException异常,但是会抛出异常LockedException

我的问题是

  1. 为什么spring-security正在处理用户进行进一步的身份验证,而凭据特别是密码不正确?
  2. 即使用户密码无效,在应用程序中显示“用户已锁定”消息也是一种好习惯吗?
  3. 我如何设法生成/捕获BadCredentialsException无效的密码和锁定的用户?

任何帮助,将不胜感激。身份验证提供程序实现代码为

@Component("authenticationProvider")
public class LoginAuthenticationProvider extends DaoAuthenticationProvider {

    @Autowired
    UserDAO userDAO;

    @Autowired
    @Qualifier("userDetailsService")
    @Override
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        super.setUserDetailsService(userDetailsService);
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        try {
            Authentication auth = super.authenticate(authentication);
            // if reach here, means login success, else exception will be thrown

            // reset the user attempts
            userDAO.resetPasswordRetryAttempts(authentication.getName());

            return auth;
        } catch (BadCredentialsException ex) {
            // invalid login, update user attempts
            userDAO.updatePasswordRetryAttempts(authentication.getName(), PropertyUtils.getLoginAttemptsLimit());
            throw ex;
        } catch (LockedException ex) {
            // this user is locked
            throw ex;
        } catch (AccountExpiredException ex) {
            // this user is expired
            throw ex;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
    }

}

问题答案:

你问:

Spring Security:抛出LockedException而不是BadCredentialsException,为什么?

这是因为Spring Security将首先检查该帐户是否存在并有效,然后再检查密码。

更具体:在中完成AbstractUserDetailsAuthenticationProvider.authenticate。在 非常简短的
说明中,该方法以这种方式工作:

user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
...
preAuthenticationChecks.check(user);
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
...
postAuthenticationChecks.check(user);
  • retrieveUser -加载用户
  • preAuthenticationChecks.check(user);- DefaultPreAuthenticationChecks:检查锁定…
  • additionalAuthenticationChecks -检查密码
  • postAuthenticationChecks.check(user);- DefaultPostAuthenticationChecks检查未过期的凭证

好处是,preAuthenticationChecks并且postAuthenticationChecks接口的引用,UserDetailsChecker因此您可以更改它们。只需实现自己的两个UserDetailsChecker,一个用于pre的Null-
Implementation,一个用于检查所有内容的post:

  • !user.isAccountNonLocked()
  • !user.isEnabled()
  • !user.isAccountNonExpired()
  • !user.isCredentialsNonExpired()


 类似资料:
  • 使用Spring Security 4.0.2。发布 对于使用Spring Security框架的基本用户身份验证,我实现了Spring Security性DaoAuthenticationProvider 当用户尝试使用正确的用户名登录时,错误的密码和用户的帐户已被锁定,那么我预计Spring Security身份验证模块将引发BadCredentialsException,但它会引发Locke

  • 我正在尝试使用HttpWebRequest验证Url的存在。我发现了一些基本上这样做的示例: 但是,如果url确实损坏了,它不会返回响应,而是抛出异常。 我将代码修改为: 这似乎终于做到了我想要的。 但是我想知道,为什么请求会抛出异常,而不是返回带有NotFindstatus代码的响应?

  • 我在服务层的spring-boot应用程序中使用了Hystrix(Camden.sr7版本),而没有回退方法。Service的方法之一如下所示: 对于这样的响应,不清楚实际上是从哪个方法抛出异常的。如果我将版本更改为brixton.sr5(以前的版本),它将返回清晰的响应: 因此Hystrix的新版本(实际上是spring-cloud-dependencies的新版本)不会抛出HystrixRun

  • 下面是我的代码。当我运行它时,我在线程“main”java.lang.IndexOutOfBoundsException:Index:3、Size:2中得到异常,而不是我的异常消息。谁能解释一下我做错了什么,为什么会这样?谢谢!

  • 既然我们可以在Javascript中使用关键字抛出任何东西,那么我们就不能直接抛出一个错误消息字符串吗? 有人知道这里面有什么陷阱吗? 让我对此添加一些背景:在JavaScript世界中,人们通常依赖参数检查而不是使用try-catch机制,因此只使用抛出致命错误是有意义的。不过,为了能够捕捉一些系统错误,我必须为我自己的错误使用一个不同的类,而不是创建错误的子类,我认为我应该只使用String。

  • 问题内容: 我在编写Traveling Salesman程序时遇到了这个问题。对于内部循环,我尝试了 但是在该列表中添加另一个点时会导致被抛出。 但是,当我将循环更改为 循环运行良好,没有引发异常。 这两个都是for循环,那么为什么一个抛出异常却另一个没有抛出异常呢? 问题答案: 正如其他人解释的那样,迭代器检测到对基础集合的修改,这是一件好事,因为它可能会导致意外的行为。 想象一下下面的无迭代器