In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces "how to understand AuthenticationManagerBuilder in spring security". In daily operation, I believe many people have doubts about how to understand AuthenticationManagerBuilder in spring security. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to understand AuthenticationManagerBuilder in spring security". Next, please follow the editor to study!
1. Preliminary understanding
In Spring Security, the class used to handle authentication is AuthenticationManager, which is also called the authentication manager.
AuthenticationManager specifies how Spring Security's filter performs authentication and returns an authenticated Authentication object after successful authentication. AuthenticationManager is an interface, and we can customize its implementation, but usually we use more ProviderManager provided by the system.
1.1 ProviderManager
ProviderManager is the most commonly used AuthenticationManager implementation class of.
ProviderManager manages a list of AuthenticationProvider, each AuthenticationProvider is an authenticator, and different AuthenticationProvider is used to handle the authentication of different Authentication objects. A complete authentication process may go through multiple AuthenticationProvider.
ProviderManager is equivalent to representing multiple AuthenticationProvider, and their relationship is shown below:
1.2 AuthenticationProvider
AuthenticationProvider defines the validation logic in Spring Security. Let's take a look at the definition of AuthenticationProvider:
Public interface AuthenticationProvider {
Authentication authenticate (Authentication authentication)
Throws AuthenticationException
Boolean supports (Class authentication)
}
As you can see, there are only two methods in AuthenticationProvider:
The authenticate method is used for authentication, which is to verify the user's identity. Supports is used to determine whether the current AuthenticationProvider supports the corresponding Authentication.
In a complete authentication, there may be multiple AuthenticationProvider, and these multiple AuthenticationProvider are managed by ProviderManager.
The most commonly used AuthenticationProvider implementation class is DaoAuthenticationProvider.
1.3 Parent
Each ProviderManager manages multiple AuthenticationProvider, and each ProviderManager can be configured with a parent. If the authentication fails in the current ProviderManager, you can continue to perform authentication in its parent. The so-called parent instance is generally also ProviderManager, that is, ProviderManager's parent or ProviderManager. You can refer to the following architecture diagram:
As you can see from the above analysis, the initialization of AuthenticationManager is divided into two parts, one global AuthenticationManager, that is, parent, and the other local AuthenticationManager. Let's first come to the conclusion that we can configure multiple HttpSecurity in a system (see Spring Security can have multiple filter chains at the same time? Each HttpSecurity has a corresponding AuthenticationManager instance (local AuthenticationManager), and these local AuthenticationManager instances all have a common parent, which is the global AuthenticationManager.
Next, we verify our above conclusion through source code analysis.
two。 Source code analysis
In the last article, Song GE has analyzed several common implementation classes of SecurityBuilder, such as AbstractSecurityBuilder, AbstractConfiguredSecurityBuilder, and HttpSecurityBuilder, which I will not repeat in this article.
Let's look directly at AuthenticationManagerBuilder and first look at one of its inheritance relationships:
As you can see, AuthenticationManagerBuilder already automatically has the functionality of its parent class.
The source code of AuthenticationManagerBuilder is relatively long, so let's take a look at several key methods:
Public class AuthenticationManagerBuilder
Extends
AbstractConfiguredSecurityBuilder
Implements ProviderManagerBuilder {
Public AuthenticationManagerBuilder (ObjectPostProcessor objectPostProcessor) {
Super (objectPostProcessor, true)
}
Public AuthenticationManagerBuilder parentAuthenticationManager (
AuthenticationManager authenticationManager) {
If (authenticationManager instanceof ProviderManager) {
EraseCredentials (ProviderManager) authenticationManager))
.isEraseCredentialsAfterAuthentication ()
}
This.parentAuthenticationManager = authenticationManager
Return this
}
Public InMemoryUserDetailsManagerConfigurer inMemoryAuthentication ()
Throws Exception {
Return apply (new InMemoryUserDetailsManagerConfigurer ())
}
Public JdbcUserDetailsManagerConfigurer jdbcAuthentication ()
Throws Exception {
Return apply (new JdbcUserDetailsManagerConfigurer ())
}
Public DaoAuthenticationConfigurer userDetailsService (
T userDetailsService) throws Exception {
This.defaultUserDetailsService = userDetailsService
Return apply (new DaoAuthenticationConfigurer (
UserDetailsService))
}
@ Override
Protected ProviderManager performBuild () throws Exception {
If (! isConfigured ()) {
Logger.debug ("No authenticationProviders and no parentAuthenticationManager defined. Returning null.")
Return null
}
ProviderManager providerManager = new ProviderManager (authenticationProviders
ParentAuthenticationManager)
If (eraseCredentials! = null) {
ProviderManager.setEraseCredentialsAfterAuthentication (eraseCredentials)
}
If (eventPublisher! = null) {
ProviderManager.setAuthenticationEventPublisher (eventPublisher)
}
ProviderManager = postProcess (providerManager)
Return providerManager
}
}
First, we can set the parent for an AuthenticationManager by calling the parentAuthenticationManager method. The purpose of inMemoryAuthentication and jdbcAuthentication is to configure data sources, so I won't repeat them here. Finally, there is the performBuild method, which is used to build an AuthenticationManager based on the current AuthenticationManagerBuilder. AuthenticationManager itself is an interface, and its default implementation is ProviderManager, so what is built here is ProviderManager. When you build a ProviderManager, you pass in the authenticationProviders, which is all the AuthenticationProvider managed by the ProviderManager, and the parent of the ProviderManager (which is actually a ProviderManager).
However, there is a problem with our own configuration, that is, we do not configure the parent of ProviderManager. If we do not configure it, if the authentication fails in the current ProviderManager, we will simply throw a failure instead of going to the parent to verify it again (generally speaking, it is not necessary. If the system is complex, it may be necessary).
AuthenticationManagerBuilder also has an implementation class called DefaultPasswordEncoderAuthenticationManagerBuilder, which is defined as an internal class in WebSecurityConfigurerAdapter and AuthenticationConfiguration respectively, but the content of DefaultPasswordEncoderAuthenticationManagerBuilder is relatively simple. It rewrites several methods of the parent class AuthenticationManagerBuilder and configures a new PasswordEncoder, so I will not list the source code here, and interested partners can check it for themselves. But this is not to say that DefaultPasswordEncoderAuthenticationManagerBuilder is not important, because in later use, DefaultPasswordEncoderAuthenticationManagerBuilder is basically used to build AuthenticationManagerBuilder.
Okay, this is AuthenticationManagerBuilder.
So when did you build AuthenticationManager through AuthenticationManagerBuilder?
This involves our old acquaintance WebSecurityConfigurerAdapter. Today we will mainly look at how to enable the initialization of AuthenticationManager in WebSecurityConfigurerAdapter.
2.1 initialization process
In the initialization process, Brother Song has to introduce an AuthenticationConfiguration class to you first. This class can be understood as a global assigned class, which is full of configurations of global attributes:
@ Configuration (proxyBeanMethods = false)
@ Import (ObjectPostProcessorConfiguration.class)
Public class AuthenticationConfiguration {
@ Bean
Public AuthenticationManagerBuilder authenticationManagerBuilder (
ObjectPostProcessor objectPostProcessor, ApplicationContext context) {
LazyPasswordEncoder defaultPasswordEncoder = new LazyPasswordEncoder (context)
AuthenticationEventPublisher authenticationEventPublisher = getBeanOrNull (context, AuthenticationEventPublisher.class)
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder (objectPostProcessor, defaultPasswordEncoder)
If (authenticationEventPublisher! = null) {
Result.authenticationEventPublisher (authenticationEventPublisher)
}
Return result
}
@ Bean
Public static GlobalAuthenticationConfigurerAdapter enableGlobalAuthenticationAutowiredConfigurer (
ApplicationContext context) {
Return new EnableGlobalAuthenticationAutowiredConfigurer (context)
}
@ Bean
Public static InitializeUserDetailsBeanManagerConfigurer initializeUserDetailsBeanManagerConfigurer (ApplicationContext context) {
Return new InitializeUserDetailsBeanManagerConfigurer (context)
}
@ Bean
Public static InitializeAuthenticationProviderBeanManagerConfigurer initializeAuthenticationProviderBeanManagerConfigurer (ApplicationContext context) {
Return new InitializeAuthenticationProviderBeanManagerConfigurer (context)
}
Public AuthenticationManager getAuthenticationManager () throws Exception {
If (this.authenticationManagerInitialized) {
Return this.authenticationManager
}
AuthenticationManagerBuilder authBuilder = this.applicationContext.getBean (AuthenticationManagerBuilder.class)
If (this.buildingAuthenticationManager.getAndSet (true)) {
Return new AuthenticationManagerDelegator (authBuilder)
}
For (GlobalAuthenticationConfigurerAdapter config: globalAuthConfigurers) {
AuthBuilder.apply (config)
}
AuthenticationManager = authBuilder.build ()
If (authenticationManager = = null) {
AuthenticationManager = getAuthenticationManagerBean ()
}
This.authenticationManagerInitialized = true
Return authenticationManager
}
@ Autowired
Public void setApplicationContext (ApplicationContext applicationContext) {
This.applicationContext = applicationContext
}
@ Autowired
Public void setObjectPostProcessor (ObjectPostProcessor objectPostProcessor) {
This.objectPostProcessor = objectPostProcessor
}
Private static class EnableGlobalAuthenticationAutowiredConfigurer extends
GlobalAuthenticationConfigurerAdapter {
Private final ApplicationContext context
Private static final Log logger = LogFactory
.getLog (EnableGlobalAuthenticationAutowiredConfigurer.class)
EnableGlobalAuthenticationAutowiredConfigurer (ApplicationContext context) {
This.context = context
}
@ Override
Public void init (AuthenticationManagerBuilder auth) {
Map beansWithAnnotation = context
.getBeansWithAnnotation (EnableGlobalAuthentication.class)
If (logger.isDebugEnabled ()) {
Logger.debug ("Eagerly initializing" + beansWithAnnotation)
}
}
}
}
Here we first build an AuthenticationManagerBuilder instance, which is the AuthenticationManagerBuilder used to build the global AuthenticationManager, the specific construction process is in the following getAuthenticationManager method. But the global AuthenticationManagerBuilder here is not always useful. Why? Take a look at the analysis below. There are also some initializeXXX methods for building global UserDetailService and AuthenticationProvider, which can be used as an understanding, because these Bean are not used normally, and these default Bean are configured only when the getAuthenticationManager method is called, and the getAuthenticationManager method is called, which means that we have to use the AuthenticationManager configured by the default system as the parent, and in actual use We don't usually use AuthenticationManager as parent, which is the default configuration of the system. We will more or less customize it ourselves.
This is the main function of AuthenticationConfiguration, it mainly provides some global Bean, although these global Bean will be initialized, but not necessarily used.
So when to use it and when not to use it, it has something to do with WebSecurityConfigurerAdapter. There are three important methods in WebSecurityConfigurerAdapter that involve the initialization of AuthenticationManager. The first is the setApplicationContext method:
Public void setApplicationContext (ApplicationContext context) {
This.context = context
ObjectPostProcessor objectPostProcessor = context.getBean (ObjectPostProcessor.class)
LazyPasswordEncoder passwordEncoder = new LazyPasswordEncoder (context)
AuthenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder (objectPostProcessor, passwordEncoder)
LocalConfigureAuthenticationBldr = new DefaultPasswordEncoderAuthenticationManagerBuilder (objectPostProcessor, passwordEncoder) {
@ Override
Public AuthenticationManagerBuilder eraseCredentials (boolean eraseCredentials) {
AuthenticationBuilder.eraseCredentials (eraseCredentials)
Return super.eraseCredentials (eraseCredentials)
}
@ Override
Public AuthenticationManagerBuilder authenticationEventPublisher (AuthenticationEventPublisher eventPublisher) {
AuthenticationBuilder.authenticationEventPublisher (eventPublisher)
Return super.authenticationEventPublisher (eventPublisher)
}
}
}
In this method, two AuthenticationManagerBuilder instances that are almost identical are created. Why are there two? The first authenticationBuilder is a local AuthenticationManagerBuilder, which will be passed into HttpSecurity in the future to build a local AuthenticationManager;. The second localConfigureAuthenticationBldr is an AuthenticationManagerBuilder used to build a global AuthenticationManager.
Some friends will ask, isn't the global AuthenticationManager created in AuthenticationConfiguration from the very beginning? Why is there another one here? Yes, the current localConfigureAuthenticationBldr can be disabled, if disabled, the AuthenticationManagerBuilder provided in AuthenticationConfiguration will be used, and if not disabled, localConfigureAuthenticationBldr will be used to build the global AuthenticationManager.
Another method is the getHttp method:
Protected final HttpSecurity getHttp () throws Exception {
If (http! = null) {
Return http
}
AuthenticationEventPublisher eventPublisher = getAuthenticationEventPublisher ()
LocalConfigureAuthenticationBldr.authenticationEventPublisher (eventPublisher)
AuthenticationManager authenticationManager = authenticationManager ()
AuthenticationBuilder.parentAuthenticationManager (authenticationManager)
Map
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.