java我什么时候应该在Spring启动应用程序中覆盖Spring Security中的配置(AuthenticationManagerBuilder auth)?
我正在一个Spring Boot应用程序中学习Spring安全性,我有一个非常简单的例子。我发现,如果我对configure(AuthenticationManagerBuilder auth)
进行注释,没有什么区别。如果我使用或不使用它,我有相同的输出,我需要用硬编码的凭证登录
@Configuration
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// private final MyUserDetailsService myUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic();
}
// @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.userDetailsService(myUserDetailsService);
// }
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
MyUserDetails服务类:
@Service
public class MyUserDetailsService implements UserDetailsService {
private static final String USERNAME = "john";
private static final String PASSWORD = "$2a$10$fDDUFA8rHAraWnHAERMAv.4ReqKIi7mz8wrl7.Fpjcl1uEb6sIHGu";
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
if (!userName.equals(USERNAME)) {
throw new UsernameNotFoundException(userName);
}
return new User(USERNAME, PASSWORD, new ArrayList<>());
}
}
RestController:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello World!";
}
}
我想知道实现UserDetailsService
接口是否等同于重写configure(AuthenticationManagerBuilder auth)
。谢谢大家!
# 1 楼答案
不,实现UserDetailsService接口并不等同于覆盖配置(AuthenticationManagerBuilder验证)
如果覆盖UserDetailsService并通过覆盖loadUserByUsername()验证用户名和密码,那么在您的情况下,它是静态值(我建议静态用户使用inMemoryAuthentication)
您需要自动连接UserDetailsService
及
这将告诉您的authenticationManager使用已实现用于身份验证的userDetailsService
# 2 楼答案
要完全关闭默认的web应用程序安全配置,可以添加一个带有
@EnableWebSecurity
的bean,如spring boot documentation(第4.10.1.MVC安全部分)中所述@EnableWebSecurity
是一个标记注释。它允许Spring查找(它是一个@Configuration
,因此,@Component
)并自动将类应用于全局WebSecurity
# 3 楼答案
您正在使用
@Service
注释,该注释在组件扫描时创建UserDetailsService
的bean。无需在AuthenticationManagerBuilder
中再次指定它如果不使用@Service注释,则可以在
WebSecurityConfigurerAdapter
中通过跨过AuthenticationManagerBuilder
来手动配置它# 4 楼答案
不,不一样
应用程序中作为bean提供的用户详细信息服务在global身份验证管理器(^{} )中注册,并且是所有本地身份验证管理器的回退
根据应用程序设置,可以有多个本地身份验证管理器。每个本地身份验证管理器将使用配置为
configure(AuthenticationManagerBuilder auth)
的默认用户详细信息服务如果您有不同的授权/身份验证要求,并且希望插入自己的身份验证提供程序以满足该要求,或者添加任何内置提供程序(如ldap和内存中提供程序),则应该重写。您还可以直接使用如下所示的http安全bean来实现
所有身份验证提供程序都将添加到^{} ,并一直尝试,直到找到一个
默认情况下,在不提供任何内容的情况下(即不提供用户详细信息服务或不覆盖身份验证管理器),您将拥有默认的全局身份验证管理器和自动配置的用户详细信息管理器(即用户密码
InMemoryUserDetailsManager
实现,如UserDetailsServiceAutoConfiguration
自动配置中配置的)因此,当您提供用户详细信息服务应用程序bean时,自动配置将退出,现在您的全局身份验证管理器将使用提供的bean进行配置
更多详情^{}
^{} 很好地解释了这一切是如何结合在一起的
我还想对SpringSecurityAuthenticationManager进行更详细的介绍,这很容易被忽视
正如我前面提到的,有全局身份验证管理器和本地身份验证管理器。如果需要,在配置每一个时都要特别小心
这在全局身份验证管理器注释的java文档中进行了解释
EnableGlobalAuthentication
导入配置AuthenticationConfiguration
负责为全局身份验证管理器设置默认配置AuthenticationConfiguration
配置两个关键部分,以创建身份验证管理器-用户详细信息和身份验证提供程序使用
InitializeUserDetailsBeanManagerConfigurer
配置用户详细信息,使用InitializeAuthenticationProviderBeanManagerConfigurer
配置身份验证提供程序。这两个必需的bean都是在应用程序上下文中查找的——这就是您的用户详细信息服务在全局身份验证管理器中注册的方式GlobalMethodSecurityConfiguration
和WebSecurityConfigurerAdapter
是全局身份验证管理器的使用者WebSecurityConfigurerAdapter
可用于创建和配置本地身份验证管理器(添加新的身份验证提供程序),也通常用于在应用程序中具有不同的身份验证/授权要求,如mvc与rest和public与admin端点单独使用spring security
@EnableWebSecurity
触发上述流,作为spring security过滤器链设置的一部分。使用spring引导时,相同的流由spring security自动配置触发在SpringSecurity5.4版本中,您可以将http安全性定义为bean,而无需扩展WebSecurityConfigureAdapter类。Spring boot在2.4.0版本中将对此提供支持。更多详情^{}
# 5 楼答案
我想知道实现UserDetailsService接口是否等同于覆盖
configure(AuthenticationManagerBuilder auth)
不,它们是不可比较的强>
及
因此,很明显,当您使用
UserDetailsService
时,这意味着您正在使用DaoAuthenticationProvider
从底层数据库获取用户详细信息注意:
AuthenticationProvider
是从不同来源/存储库获取用户信息的抽象,并验证检索到的信息是否与用户提供的信息相似让我们看一个示例,配置如下所示:
而且
YourUserDetailServiceImpl
必须重写loadUserByUsername()
以获取使用过的详细信息# 6 楼答案
UserDetailsService
UserDetailsService界面用于检索与用户相关的数据。它有一个名为
loadUserByUsername()
的方法,可以覆盖来定制查找用户的过程。为了提供我们自己的用户服务,我们需要实现用户详细信息服务接口loadUserByUsername(String username)
返回用户详细信息,它是org.springframework.security.core.userdetails
的一部分,由{我们还可以通过实现UserDetails接口来定制
org.springframework.security.core.userdetails.User
(这里用作new User(USERNAME, PASSWORD, new ArrayList<>())
)在这里,我分享使用UserDetailsService服务的理想方式
when loadUserByUsername is invoked?
如上所述,DAOAuthenticationProvider实例通常会调用它来验证用户。例如,当提交用户名和密码时,将调用UserdetailsService查找该用户的密码,以查看其是否正确。它通常还会提供一些关于用户的其他信息,例如权限和您可能希望登录用户访问的任何自定义字段(例如电子邮件)
In-Memory Authentication
在这里,您使用了用户名和密码的静态值,理想情况下可以使用In-Memory Authentication进行如下配置
Spring Security的}的身份验证
InMemoryUserDetailsManager
实现UserDetailsService
以支持在内存中检索的基于用户名/密码的身份验证InMemoryUserDetailsManager
通过实现UserDetailsManager
接口,提供对UserDetails
的管理^当Spring Security配置为接受用户名/密码进行身份验证时,它使用基于{配置(AuthenticationManagerBuilder验证)
此方法使用
AuthenticationManagerBuilder
,它在内部使用SecurityBuilder创建AuthenticationManager。允许轻松构建内存身份验证、LDAP身份验证、基于JDBC的身份验证、添加UserDetailsService和添加 AuthenticationProviderHow Spring Security add/configure AuthenticationManagerBuilder?
否