我正在尝试开始使用 Spring Boot,以便可以在未来的项目中使用它。
然而,在我实现了包含一些简单用户服务(的实现UserDetailsService
)的“身份验证”库之后,我尝试将其集成到我的新 Spring Boot 应用程序中。
因为UserService
它在一个单独的 JAR 中,所以我必须更改 Spring 查找的基本包,以便它们被加载。
一切都很好,我的应用程序启动,端点按预期工作。我被重定向到登录,并尝试从数据库中使用我的用户登录。这里问题就出现了。我明白了No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken
。
在四处挖掘之后,我发现如果删除基包类以扫描并使用内存 UserDetailService 一切都按预期工作。我想使用DaoAuthenticationProvider
应该只使用我的UserDetailService
实现的默认值。
当我改变basePackages
或者我错过了其他东西时,Spring不会再加载这个了吗?
您可以在这里看到我尝试过的内容:(不要担心代码在 Scala 中,我只是在评估它们如何协同工作)
@SpringBootApplication(scanBasePackages = Array("ro.sandd", "spring.framework"))
@EnableJpaRepositories(basePackages = Array("ro.sandd"))
@EntityScan(basePackages = Array("ro.sandd"))
class SpringDemoApplication
object SpringDemoApplication extends App {
SpringApplication.run(classOf[SpringDemoApplication]);
}
@Configuration
@EnableWebSecurity
//@Import(Array(classOf[UserService]))
//@ComponentScan(basePackageClasses = Array(classOf[UserService], classOf[DaoAuthenticationProvider]))
class WebSecurityConfig(@Autowired val userService: UserService) extends WebSecurityConfigurerAdapter with Logging {
protected override def configure(http: HttpSecurity): Unit = {
http.csrf().disable().authorizeRequests()
.antMatchers("/", "/demo").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
override def userDetailsService: UserDetailsService = {
userService
}
}
我也有一些简单的控制器,但我认为不值得看代码。另外...我可能可以提供自定义提供程序,但我的目的是使用现有的提供程序,因为对我来说似乎合适。
PS进一步调查1:
注 1 - 如果我使用@SpringBootApplication(scanBasePackageClasses = Array(classOf[UserService]))
我可以看到DaoAuthenticationProvider
加载到AuthenticationConfiguration
. 但是我的WebSecurityConfigurerAdapter
配置方法没有被调用。相反,org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration$DefaultConfigurerAdapter
被使用。
注 2 - 如果我使用 @SpringBootApplication(scanBasePackageClasses = Array(classOf[UserService], classOf[WebSecurityConfig])) 强制加载我的WebSecurityConfig
, authenticationProviders 列表为空。
所以这个WebSecurityConfig在实际使用的时候肯定是有问题的。但是......我想知道UserDetailsService
如果不使用这个类,我的工作情况如何。这就是我提供它的地方,如下所示。可能 Spring 做了一些魔法并将其注入到其他地方。
@Bean
override def userDetailsService: UserDetailsService = {
userService
}
PS进一步调查2:
我删除了上面的 @Bean 声明,一切都按预期工作。可能我已经自动装配我的 UserService 的事实足以让 Spring 将它注入它必须的地方。
无论如何,一些解释为什么当我使用覆盖方法时它不起作用会很有用。