Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the Spring Security user-defined method

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "what is the Spring Security user-defined method". In the daily operation, I believe that many people have doubts about what the Spring Security user-defined method is. The editor consulted all kinds of materials and sorted out a simple and easy-to-use operation method. I hope it will be helpful to answer the doubt of "what is the Spring Security user-defined method?" Next, please follow the editor to study!

1. Unique skill one

Let's take a look at the following code:

@ Configuration

Public class SecurityConfig {

@ Bean

UserDetailsService us () {

InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager ()

Manager.createUser (User.withUsername ("sang") .password ("{noop} 123") .roles (" admin ") .build ()

Return manager

}

@ Configuration

@ Order (1)

Static class DefaultWebSecurityConfig extends WebSecurityConfigurerAdapter {

UserDetailsService us1 () {

InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager ()

Manager.createUser (User.withUsername ("javaboy") .password ("{noop} 123") .roles (" admin "," aaa "," bbb ") .build ()

Return manager

}

@ Override

Protected void configure (HttpSecurity http) throws Exception {

Http.antMatcher ("/ foo/**")

.authorizeRequests ()

.anyRequest () .hasRole ("admin")

.and ()

.formLogin ()

.loginProcessingUrl ("/ foo/login")

.permitAll ()

.and ()

.userDetailsService (us1 ())

.csrf () .disable ()

}

}

@ Configuration

@ Order (2)

Static class DefaultWebSecurityConfig2 extends WebSecurityConfigurerAdapter {

UserDetailsService us2 () {

InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager ()

Manager.createUser (User.withUsername). Password ("{noop} 123"). Roles ("user", "aaa", "bbb"). Build ()

Return manager

}

@ Override

Protected void configure (HttpSecurity http) throws Exception {

Http.antMatcher ("/ bar/**")

.authorizeRequests ()

.anyRequest () .hasRole ("user")

.and ()

.formLogin ()

.loginProcessingUrl ("/ bar/login")

.permitAll ()

.and ()

.csrf () .disable ()

.userDetailsService (us2 ())

}

}

}

Notice that in each filter chain, I provide an instance of UserDetailsService, and then configure this instance of UserDetailsService in the configure (HttpSecurity http) method. In addition to configuring a UserDetailsService in each filter chain, I also provide a Bean for UserDetailsService, so here there are three users, so which user can log in successfully when we log in?

Let's start with the conclusion:

If the login address is / foo/login, then two users, sang and javaboy, can log in successfully. If the login address is / bar/login, then two users can log in successfully through sang and Jiangnan Dianyu.

That is, the global, public UserDetailsService is always valid, while the UserDetailsService configured for different filter chains is only valid for the current filter chain.

For convenience, memory-based UserDetailsService is used here, but you can also replace it with database-based UserDetailsService.

So next let's analyze, why is it like this?

1.1 Source Code Analysis 1.1.1 Global AuthenticationManager

First of all, note that although I have defined two filter chains, I did not rewrite the configure (AuthenticationManagerBuilder auth) method in the definition of the two filter chains. Combined with the previous article, I did not rewrite this method, which means that the global AuthenticationManager provided in AuthenticationConfiguration is valid, that is to say, the AuthenticationManager provided by the system by default will serve as the parent of other local AuthenticationManager.

So let's take a look at what is matched with the global AuthenticationManager configuration?

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

}

One step in global configuration is to traverse the globalAuthConfigurers, traverse the global xxxConfigurer, and configure it. There are three global xxxConfigurer, which are:

EnableGlobalAuthenticationAutowiredConfigurerInitializeUserDetailsBeanManagerConfigurerInitializeAuthenticationProviderBeanManagerConfigurer

InitializeUserDetailsBeanManagerConfigurer. The name is used to configure UserDetailsService. Let's take a look at:

@ Order (InitializeUserDetailsBeanManagerConfigurer.DEFAULT_ORDER)

Class InitializeUserDetailsBeanManagerConfigurer

Extends GlobalAuthenticationConfigurerAdapter {

@ Override

Public void init (AuthenticationManagerBuilder auth) throws Exception {

Auth.apply (new InitializeUserDetailsManagerConfigurer ())

}

Class InitializeUserDetailsManagerConfigurer

Extends GlobalAuthenticationConfigurerAdapter {

@ Override

Public void configure (AuthenticationManagerBuilder auth) throws Exception {

If (auth.isConfigured ()) {

Return

}

UserDetailsService userDetailsService = getBeanOrNull (

UserDetailsService.class)

If (userDetailsService = = null) {

Return

}

PasswordEncoder passwordEncoder = getBeanOrNull (PasswordEncoder.class)

UserDetailsPasswordService passwordManager = getBeanOrNull (UserDetailsPasswordService.class)

DaoAuthenticationProvider provider = new DaoAuthenticationProvider ()

Provider.setUserDetailsService (userDetailsService)

If (passwordEncoder! = null) {

Provider.setPasswordEncoder (passwordEncoder)

}

If (passwordManager! = null) {

Provider.setUserDetailsPasswordService (passwordManager)

}

Provider.afterPropertiesSet ()

Auth.authenticationProvider (provider)

}

}

}

As you can see, the inner class is defined in InitializeUserDetailsBeanManagerConfigurer. In the configure method of its inner class, getBeanOrNull is used to find the UserDetailsService instance from the container. After finding it, the DaoAuthenticationProvider is created and finally configured to the auth object.

What the getBeanOrNull method here finds from the container is actually the Bean in the Spring container, that is, the Bean where we configured the sang user at the beginning, and this Bean is given to the global AuthenticationManager, that is, the parent of all local AuthenticationManager.

1.1.2 Local AuthenticationManager

During the construction process, all HttpSecurity will pass in a local AuthenticationManagerBuilder. Once the local AuthenticationManagerBuilder is passed in, it will be stored in the shared object, and then taken out of the shared object later when it is needed. Some of the code is as follows:

Public HttpSecurity (ObjectPostProcessor objectPostProcessor

AuthenticationManagerBuilder authenticationBuilder

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.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report