在身份验证 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
的任务。
默认的UserDetails
、User
实现有2个构造函数,一个有3个参数,一个有7个参数。使用第二个根据您的业务规则正确填写enabled
,Spring Security 将完成其余的工作。
【讨论】:
以上是关于在身份验证 Spring Security + WebFlux 期间抛出和处理自定义异常的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Security 中将令牌转换为身份验证?
在 Spring WebFlux 中使用 Spring Security 实现身份验证的资源是啥
Spring Security 中用于身份验证的通用身份验证过滤器
如何在同一应用程序中使用 spring-sample 示例配置 Spring Security 基本身份验证和 SAML 身份验证