Spring -- permission restriction of Security framework

Posted by nosmasu on Tue, 22 Feb 2022 13:05:49 +0100

preface

Last blog The Security framework imposes restrictions on requests In, login authentication is added for some requests.

As long as the login is successful, you can access the restricted requests.

However, this model is certainly not enough.

For example: Taobao product page. Merchants can modify commodity prices, but customers can only see and buy commodities.

Access control based on roles or permissions

In the Security framework, there are several methods to set its permissions and roles:

  • hasAuthority method
    Whether the current principal has the specified permission. If yes, it returns true. If not, it returns false.
  • hasAnyAuthority method
    The current principal returns true if it has given multiple permissions.
  • hasRole method
    If the user has a given role, access is allowed, otherwise 403 will appear.
    Returns true if the current principal has the specified role.
  • hasAnyRole method
    The current user principal has any permission and is allowed to access.

hasAuthority method (single permission)

Whether the current principal has the specified permission. If yes, it returns true. If not, it returns false.

Then, let's set up and test.

In the configuration class, add permission restrictions on one of the interfaces.

package security.config;

import security.service.MySecurityService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

 open Security ,
// But at org springframework. boot. autoconfigure. security. servlet. In securityautoconfiguration
// org. springframework. boot. autoconfigure. security. servlet. On the websecurity enablerconfiguration class
// @ EnableWebSecurity has been marked
//@EnableWebSecurity
@Configuration
@Slf4j
public class MyConfig extends WebSecurityConfigurerAdapter {

    /**
     * Since spring is entrusted to manage the life cycle of the bean, it can be injected directly here
     */
    @Autowired
    private MySecurityService mySecurityService;

    /**
     * Authentication manager builder configuration
     * If CN security. Service. Mysecurityservice has added @ Service tag. There is no problem commenting or releasing here
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        log.info(" ******  configure  AuthenticationManagerBuilder  ********");
        // Based on memory configuration
//        auth.inMemoryAuthentication()
//                .withUser("xiangjiao")
//                .password(passwordEncoder().encode("bunana"))
//                .authorities("admin")
//                .and()
//                .withUser("123")
//                .password(passwordEncoder().encode("123456"))
//                .authorities("role");

        // Based on userDetailService
        // UserAuthenticationServiceImpl implements UserDetailsService and can be passed directly
        auth.userDetailsService(mySecurityService);
    }

    /**
     * Rights management configuration HttpSecurity
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        log.info(" ******  configure  HttpSecurity  ********");
        http.formLogin() // Support user-defined login interface jump
                .loginPage("/login.html") // Login page setup
                .loginProcessingUrl("/user/login") // Login request interface settings. The default is / login
                .defaultSuccessUrl("/test/index").permitAll() //After successful login, the path jumps
                .and()
                .authorizeRequests() // Verification request
                .antMatchers("/","/test","/test/test4","/user/login").permitAll() // Set which paths can be accessed directly without verification

                // For some interfaces, you need to log in and authenticate, and then you need to have some permissions before you can access them
                .antMatchers("/test/index").hasAuthority("admin")

                .anyRequest().authenticated()  // All requests are accessible
                .and()
                .csrf().disable(); // Turn off csrf defense



    }

    /**
     * Declare the BCryptPasswordEncoder bean object corresponding to {bcrypt};
     * In progress CN security. service. When userserviceimpl#loaduserbyusername (Java. Lang. string), injection is used
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}


In addition, you also need to check the security service. In mysecurityservice#loaduserbyusername, set its permissions.

For the time being, only the memory permission information saving test will be considered, and the database will be added later!

test

  • admin permission test
    Due to security service. Mysecurityservice#loaduserbyusername is configured with the permission of admin. Start the project directly and conduct interface access test.

http://localhost/test/index

Because you are not logged in, after visiting, you will jump to the login page!

Enter the account and password information in the corresponding database.

Click the login button to observe the phenomenon.

  • Non admin permission test
    In security service. In mysecurityservice#loaduserbyusername, use the following code

    Modify admin in to other permissions, such as users.

    Restart the project, visit the following link and observe the phenomenon:

http://localhost/test/index


hasAnyAuthority method (multiple permissions)

The current principal returns true if it has given multiple permissions.

In security service. In mysecurityservice#loaduserbyusername, all permissions of the login role set are users permissions.

In security config. In this method of myconfig#configure (org. Springframework. Security. Config. Annotation. Web. Builders. Httpsecurity) custom configuration class, replace hasAuthority with hasAnyAuthority, and modify it as follows:

test

Restart the project and re request the test:

http://localhost/test/index




Through the test, it is found that:

The login user's permission is users. Using hasAnyAuthority("admin","users") in the configuration can achieve the function of identifying permissions!

hasRole method (one permission)

If the user has a given role, access is allowed, otherwise 403 will appear.
Returns true if the current principal has the specified role.

[note] when using hasRole, the ROLE permission must be based on ROLE_ start.

Modify security config. The configuration item in myconfig #configure (org. Springframework. Security. Config. Annotation. Web. Builders. Httpsecurity) changes the request role limit to hasRole.

@Override
    protected void configure(HttpSecurity http) throws Exception {
        log.info(" ******  configure  HttpSecurity  ********");
        http.formLogin() // Support user-defined login interface jump
                .loginPage("/login.html") // Login page setup
                .loginProcessingUrl("/user/login") // Login request interface settings. The default is / login
                .defaultSuccessUrl("/test/index").permitAll() //After successful login, the path jumps
                .and()
                .authorizeRequests() // Verification request
                .antMatchers("/","/test","/test/test4","/user/login").permitAll() // Set which paths can be accessed directly without verification

                // For some interfaces, you need to log in and authenticate, and then you need to have some permissions before you can access them
                //.antMatchers("/test/index"). Hasauthority ("admin") / / hasauthority can only pass one permission value

                // hasAnyAuthority can pass multiple permission values
                // "admin","users" or "admin,users" can be written like this
                //.antMatchers("/test/index").hasAnyAuthority("admin","users")

                // Only one is allowed to be passed using hasRole
                .antMatchers("/test/index").hasRole("admin")

                .anyRequest().authenticated()  // All requests are accessible
                .and()
                .csrf().disable(); // Turn off csrf defense
    }


Secondly, in the login verification, give permission, and be sure to pay attention to ROLE_ Splice.

security.service.MySecurityService#loadUserByUsername

 List<GrantedAuthority> admin = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_admin");


Restart the service and request the test

test

http://localhost/test/index

Abnormal test

Change the permission information to security service. The following changes are made in mysecurityservice#loaduserbyusername:

Restart the project and re access the project:

http://localhost/test/index


hasAnyRole method (multiple)

The current user principal has any permission and is allowed to access.


Modify the configuration class and adopt hasAnyRole for configuration.

.antMatchers("/test/index").hasAnyRole("admin,user")

test

Restart the project and access:

http://localhost/test/index


Multiple permissions passed in loadUserByUsername

If a role has multiple permissions, it can be written directly as follows.

 List<GrantedAuthority> admin = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_user,ROLE_admin,admin");

Download code

springboot-security-06

gitee code download

Topics: Java Spring Spring Security security