Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 如何使用WebSecurity配置适配器定义自定义UserDetails服务?_Spring_Spring Boot_Spring Security - Fatal编程技术网

Spring 如何使用WebSecurity配置适配器定义自定义UserDetails服务?

Spring 如何使用WebSecurity配置适配器定义自定义UserDetails服务?,spring,spring-boot,spring-security,Spring,Spring Boot,Spring Security,我对如何正确扩展websecurityConfigureAdapter以正确使用自定义UserDetailsService并将其作为bean公开感到有点困惑。 我的意思是,有: userDetailsService():Javadoc说: 允许从中修改和访问userdetails服务 userDetailsServiceBean()而不与 ApplicationContext。开发人员应在以下情况下重写此方法: 更改userDetailsServiceBean()的实例 userDetail

我对如何正确扩展
websecurityConfigureAdapter
以正确使用自定义
UserDetailsService
并将其作为bean公开感到有点困惑。 我的意思是,有:

  • userDetailsService()
    :Javadoc说: 允许从中修改和访问
    userdetails服务
    
    userDetailsServiceBean()
    而不与
    ApplicationContext
    。开发人员应在以下情况下重写此方法: 更改
    userDetailsServiceBean()
    的实例

  • userDetailsServiceBean()
    :Javadoc说: 重写此方法以公开从中创建的
    UserDetailsService
    将(AuthenticationManagerBuilder)
    配置为bean。[…]改变 实例返回后,开发人员应进行更改
    userDetailsService()

  • 配置(AuthenticationManagerBuilder)
    :Javadoc说: […]可以使用
    authenticationManagerBean()
    方法公开 生成的
    AuthenticationManager
    作为Bean。这个
    userDetailsServiceBean()
    可用于公开上次填充的 使用创建的用户详细信息服务
    AuthenticationManagerBuilder
    作为Bean。
    UserDetailsService
    也将自动在上填充
    HttpSecurity#getSharedObject(类)
    用于其他
    SecurityContextConfigurer
    (即记忆配置器)

如果我读到这篇文章,我理解:

  • configure(AuthenticationManagerBuilder)
    配置一个
    AuthenticationManager
    ,它可以通过覆盖
    authenticationManagerBean()
    以标记
    @Bean
    来公开;要构建此
    AuthenticationManager
    配置(AuthenticationManagerBuilder)
    构建并连接
    用户详细信息服务
  • 重写
    userDetailsServiceBean()
    (用
    @Bean
    标记)允许公开以前方法构建和连接的
    UserDetailsService
  • 如果我想
    configure(AuthenticationManagerBuilder)
    使用我自己的
    UserDetailsService
    实现,我必须重写
    UserDetailsService()
    以返回它;然后重写
    userDetailsServiceBean()
所以我就这样结束了:

@覆盖
受保护的无效配置(最终身份验证ManagerBuilder身份验证)
抛出异常{
最终MyUserDetailsService userDetailsService=userDetailsService();
auth.userDetailsService(userDetailsService);
//省略了所有其他配置
}
@凌驾
受保护的MyUserDetailsService userDetailsService(){
返回新的MyUserDetailsService();
}
@豆子
@凌驾
公共UserDetailsService userDetailsServiceBean()引发异常{
返回super.userDetailsServiceBean();
}
然而,这正是困扰我和我所看到的:

  • configure(final authenticationmanager builder auth)
    的默认实现基本上不起任何作用(只是将
    disableLocalConfigureAuthenticationBldr
    设置为
    true
    ),尤其是它不调用
    userdetails服务()
    ;这是我的重写完成的,所以我通过使用
    UserDetailsService()
    ;换句话说,如果我不重写
    UserDetailsService()
    并在
    configure>中创建自定义
    UserDetailsService
    实例,则我将注入自定义的
    UserDetailsService
    实现(final AuthenticationManagerBuilder auth)
    直接获得相同的结果
  • 可能与上述内容有关:
    userDetailsService()
    的默认实现与
    userDetailsServiceBean()的默认实现完全相同
    …我希望后者迟早会委托给前者,但如果前者的默认实现实际上是相同的…我真的迷路了,我想知道为什么会提供两种不同的方法
  • 我希望,通过上述方法,我的自定义
    MyUserDetailsService
    实现会在应用程序上下文中公开,但如果我尝试在其他地方注入
    MyUserDetailsService
    实例,Springs会抱怨在我的应用程序上下文中没有这样的实例;实际上,
    userDetailsServi返回的beanceBean()
    始终是某种委托包装器;如果我插入一个通用的
    UserDetailsService
    实例并尝试使用它,我会得到一个
    IllegalStateException
    说“UserDetailsService是必需的”(org.springframework.security.config.annotation.web.configuration.websecurityConfigureAdapter.UserDetailsServiceDelegator.loadUserByUsername(String)
    中的委托机制无法检索正确的默认值
    UserDetailsService
    。)
  • 通过调试,我看到
    userDetailsService()
    被调用了两次(因此创建了
    MyUserDetailsService
    的两个不同实例),一次是由上面的
    configure(final AuthenticationManagerBuilder auth)实现调用的
    ,一次由
    org.springframework.security.config.annotation.web.configuration.websecurityConfigureAdapter.createSharedObjects()
因此,上述内容显然是不正确的(身份验证是有效的,因为正确的
UserDetailsService
被注入
AuthenticationManager
,但它无法在应用程序上下文中公开
UserDetailsService
)我可能通过简单地用
@Service
标记
MyUserDetailsService
bean,或者在我的
websecurityConfigureAdapter
扩展中编写另一个
@bean
方法来克服所有这些问题,该扩展返回我的自定义
UserDetailsService
,然后