Spring Security :为不同类型的禁用用户自定义消息

v6ylcynt  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(288)

假设用户可以被禁用,因为他没有点击电子邮件验证链接,他没有支付的服务,他没有设置2fa等。我需要一种方法,为不同的原因向用户提供不同的消息。
当我使用 org.springframework.security.core.userdetails.User 我只能设置 enabled = false spring将提供一些默认消息。
我尝试的另一个选择是实现 UserDetailsService.loadUserByUsername 然后在任何消息中抛出任何异常,但是我必须微调错误日志记录机制,以防止记录这些异常,所以我假设spring不是这样做的。
Spring是怎么处理这种情况的?

t9eec4r0

t9eec4r01#

据我所知,最好的方法是通过添加额外的身份验证检查、抛出适当的异常,然后为这些异常编写一个处理程序来扩充身份验证提供者。
我们可以扩展daoauthenticationprovider并使用它的additionalauthenticationchecks(…)方法。
我们可以抛出任何自定义异常或由适当的令牌授予者捕获的异常。下面是一个示例:

@Override
protected void additionalAuthenticationChecks(final UserDetails userDetails, final UsernamePasswordAuthenticationToken authentication) {
    final User user = userDao.findByUsername(userDetails.getUsername())
                             .orElseThrow(() -> new BadCredentialsException("Incorrect username or password."));

    if (DISABLED == user.getStatus() || SUSPENDED == user.getStatus()) {
        throw new BadCredentialsException(String.format("User account with ID [%s] is %s.", user.getUserUuid(), user.getStatus()));
    }

    if (2FA_NOT_SET == user.getStatus()) {
        throw new BadCredentialsException("Account is disabled because two-factor authentication is not set.");
    }

在本例中,resourceownerpasswordtokengranter将捕获badcredentialsexception并抛出invalidgrantexception(oauth2exception的子级)。
然后,我们可以通过扩展responseentityexceptionhandler来编写自定义异常处理程序。在这里,我们可以记录异常并准备自定义错误响应。以下是供参考的示例代码:

@ExceptionHandler({OAuth2Exception.class})
public ResponseEntity<Object> handleOAuth2Exception(final OAuth2Exception exception, final WebRequest request) {

    return handleExceptionInternal(exception,
                                   ErrorOutputDto.create(exception.getOAuth2ErrorCode(), exception.getMessage()),
                                   new HttpHeaders(),
                                   HttpStatus.valueOf(exception.getHttpErrorCode()),
                                   request);
}

相关问题