Spring security 如何在SpringWebFlux安全中实现多种身份验证方法?

Spring security 如何在SpringWebFlux安全中实现多种身份验证方法?,spring-security,spring-webflux,Spring Security,Spring Webflux,我想在我的应用程序中提供两种身份验证方法,一种是基本身份验证(用户),另一种是某种基于令牌的身份验证(技术用户)。我知道我需要一个定制的ReactiveAuthenticationManager,但我找不到全局的线索。(实际上,对于MVC只有很少的见解,而对于WebFlux则没有。) 1) 如何在基于令牌的方法中填充身份验证的名称和凭据?如果我将Spring Security配置为使用httpBasic,那么它已经被填充了。需要某种过滤器吗 2) 如何在身份验证管理器中区分凭据的来源?我是否必须

我想在我的应用程序中提供两种身份验证方法,一种是基本身份验证(用户),另一种是某种基于令牌的身份验证(技术用户)。我知道我需要一个定制的
ReactiveAuthenticationManager
,但我找不到全局的线索。(实际上,对于MVC只有很少的见解,而对于WebFlux则没有。)

1) 如何在基于令牌的方法中填充身份验证的名称和凭据?如果我将Spring Security配置为使用httpBasic,那么它已经被填充了。需要某种过滤器吗

2) 如何在身份验证管理器中区分凭据的来源?我是否必须在userRepository中查找,如果没有找到,还必须在technicalUserRepository中查找


3) 我是否必须重写SecurityContextRepository?所有的教程都这样做,但我不认为有任何理由这样做。到底是什么?消息来源称“SecurityContextRepository类似于常规spring security中提供的比较用户用户名和密码的userDetailsService。”但我认为他的意思是
ReactiveUserDetailsService
(顺便说一句,
UserDetailsService
ReactiveUserDetailsService
都不这样做,只是为了用户查找)。

由于我在Webflux方面表现不错,并且我与oauth2进行了大量的合作,我将尝试回答您的一些问题

1)如何在中填充身份验证的名称和凭据 基于令牌的方法?如果我将Spring安全性配置为使用httpBasic 已经有人住了。需要某种过滤器?

令牌从不包含凭据。令牌是在完成身份验证后颁发的。因此,通常您针对发出服务进行身份验证。在您针对该服务对自己进行身份验证后,您将获得一个令牌

如果它是oauth2标记,那么该标记本身就是一个随机字符串。它不包含有关用户本身的数据。将此令牌(使用适当的头)发送到使用spring security的服务时。Spring security有一个令牌过滤器,它基本上会检查令牌是否有效,通常是通过将令牌发送给颁发者并询问“此令牌有效吗?”

如果使用jwt,其不同之处在于,jwt必须包含一些信息,如发布者、范围、主题等。但基本上是一样的,有一个内置的过滤器,通过将jwt发送给发布者来验证jwt(或者使用服务从发卡机构获取的jwk,这样它就可以验证jwt的完整性,而无需额外请求)

2)如何在身份验证管理器中区分凭据的来源?我是否必须在userRepository和technicalUserRepository(如果找不到)中查找?

您通常不会为不同的url路径定义多个SecurityWebFilterChain。我在Webflux Spring安全性中没有这样做,但在常规Spring应用程序中就是这样做的,我看不出有什么不同。除非你在做一些疯狂的事

3)我必须覆盖SecurityContextRepository吗?所有的教程都这样做,但我不认为有任何理由这样做。到底是什么?该消息来源指出,“SecurityContextRepository类似于常规spring security中提供的UserDetails服务,用于比较用户的用户名和密码。”但我认为他指的是ReactiveUserDetails服务(顺便说一句,UserDetails服务和ReactiveUserDetails服务都不这样做,只是用于用户查找)。

这里的答案可能是否定的。您可以看到SpringSecurity4对oauth2的支持非常差,尤其是JWT。所以人们习惯于编写自己的JWT解析器。当SpringSecurity5出现时,spring实现了一个jwt过滤器,您可以配置并使用内置的。但是有很多过时的Spring安全教程,最重要的是有很多开发人员没有阅读官方文档

他们大多在谷歌上搜索教程,获取错误的信息,然后再进行研究

但很容易解释:

SecurityContentExtrepository 如果您具有基于会话的身份验证(服务器与客户端建立会话),则在请求期间,它会将SecurityContext(会话)存储在ThreadLocal中。但是一旦请求结束,会话就会丢失,除非我们将其存储在某个地方。
SecurityContextPersistenceFilter
将使用
SecurityContextRepository
从ThreadLocal提取会话并将其存储,最常见的是将其存储在HttpSession中

AuthenticationManager 如果要执行自定义身份验证过程,请重写此选项。示例如果要验证某些内容,请调用自定义LDAP、数据库等。您可以在此处执行身份验证。但是请记住,大多数标准登录(如ldap、sql Server、basic login等)已经实现了预构建的可配置管理器,当您选择什么登录类型时,如
.httpBasic()
,您将获得预实现的AuthenticationManager

UserDetailsManager 当您希望在UserDetailsManager中创建自定义UserDetails对象(通常也称为主体)时,您可以覆盖此选项。您可以执行数据库查找和获取用户,然后生成并返回UserDetails对象

这两个接口是最常见的自定义实现,如果需要基本身份验证/基于会话的身份验证,可以使用这两个接口

如果你想做代币,你必须考虑,谁是代币发行人?通常,颁发者是独立的,所有服务都只获取令牌并针对颁发者验证它们

我希望这能解释一些问题。我在公共汽车上写了这封信,所以有些东西可能是错的,不是100%正确的等等。

非常感谢