在身份验证 Spring Security + WebFlux 期间抛出和处理自定义异常

Posted

技术标签:

【中文标题】在身份验证 Spring Security + WebFlux 期间抛出和处理自定义异常【英文标题】:Throw and handle custom exception during authentication Spring Security + WebFlux 【发布时间】:2019-06-05 03:57:03 【问题描述】:

我试图在身份验证期间在 WebFlux 中引发自定义异常,并使用 ControllerAdvice (@ExceptionHandler) 处理它。不幸的是,它没有被传播,如果我抛出异常,我会得到 HTTP 500,如果我将异常返回为 Mono.error(),我会得到 HTTP 401

@Override //in authentication service
public Mono<UserDetails> findByUsername(String username) 
    //find user by username from database, 
    //if not enabled, throw a custom exception, 
    //if doesn't exist, throw UsernameNotFoundException, 
    //return org.springframework.security.core.userdetails.User otherwise.


@ExceptionHandler //in controller advice
public Mono<HttpStatus> handleException(MyCustomExceptionThrownFromFindByUsername ex) 
    //implemented

有什么方法可以帮助异常进入 ExceptionHandler 吗?

【问题讨论】:

为什么? Spring Security 已经为您完成了使用启用用户的检查,所以为什么要在不负责的地方进行检查。 @M.Deinum 实际上没有,或者我做错了什么,org.springframework.security.core.userdetails.User 只关心用户名、密码和权限。 不,它没有......它实现了UserDetails,它有isEnabled......有一个构造函数需要4个额外的布尔值来指示不同的用户状态。它们的默认值为true。使用正确的构造函数,让 Spring Security 处理其余的。同样不管错误 Spring Security 会发出 401。你不想从安全角度提供更多细节......(如果黑客做了蛮力并获得更多帐户被禁用等信息,他知道这是一个现有帐户)。 @M.Deinum 即使我为此使用了错误的 UserDetails 实现,我很好奇我的异常是如何消失的,我仍在学习框架。 @M.Deinum 我以某种方式忽略了另一个构造函数。 :) 如果您将此添加为答案,我会接受。 【参考方案1】:

UserDetailsService(reactive 和 non-reactive)的任务是根据 username 检索用户。不多也不少。检查用户是否启用被委派给UserDetailsChecker,它调用UserDetails 实现上的一些方法并做出相应的反应。不要在这里尝试做更多,因为这不是UserDetailsService 的任务。

默认的UserDetailsUser实现有2个构造函数,一个有3个参数,一个有7个参数。使用第二个根据您的业务规则正确填写enabled,Spring Security 将完成其余的工作。

【讨论】:

以上是关于在身份验证 Spring Security + WebFlux 期间抛出和处理自定义异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Security 中将令牌转换为身份验证?

基于 Spring Security 令牌的身份验证

在 Spring WebFlux 中使用 Spring Security 实现身份验证的资源是啥

Spring Security 中用于身份验证的通用身份验证过滤器

如何在同一应用程序中使用 spring-sample 示例配置 Spring Security 基本身份验证和 SAML 身份验证

如何在 Spring Boot + Spring Security 中添加一些身份验证步骤?