SpringBoot2 integrates Spring Security framework to realize user rights security management

This article source code: GitHub. Click here || GitEE. Click here

Introduction to Security

1. Basic concepts

Spring Security is a security framework that can provide declarative secure access control solutions for Spring-based enterprise applications. It provides a set of beans that can be configured in Spring application context. It makes full use of Spring's IOC, DI, AOP (Aspect-Oriented Programming) functions, provides declarative security access control functions for application systems, and reduces the work of writing a lot of repetitive code for security control.

2. Interpretation of Core API

1),SecurityContextHolder

The most basic object is the current session user authentication, privileges, authentication and other core data. SecurityContextHolder uses ThreadLocal policy by default to store authentication information and thread-bound policy. When the user exits, the authentication information of the current thread is automatically cleared.

Initialization source code: ThreadLocal thread is obviously used.

private static void initialize() {
    if (!StringUtils.hasText(strategyName)) {
        strategyName = "MODE_THREADLOCAL";
    }
    if (strategyName.equals("MODE_THREADLOCAL")) {
        strategy = new ThreadLocalSecurityContextHolderStrategy();
    } else if (strategyName.equals("MODE_INHERITABLETHREADLOCAL")) {
        strategy = new InheritableThreadLocalSecurityContextHolderStrategy();
    } else if (strategyName.equals("MODE_GLOBAL")) {
        strategy = new GlobalSecurityContextHolderStrategy();
    } else {
        try {
            Class<?> clazz = Class.forName(strategyName);
            Constructor<?> customStrategy = clazz.getConstructor();
            strategy = (SecurityContextHolderStrategy)customStrategy.newInstance();
        } catch (Exception var2) {
            ReflectionUtils.handleReflectionException(var2);
        }
    }
    ++initializeCount;
}

2),Authentication

source code

public interface Authentication extends Principal, Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    Object getCredentials();
    Object getDetails();
    Object getPrincipal();
    boolean isAuthenticated();
    void setAuthenticated(boolean var1) throws IllegalArgumentException;
}

Source code analysis

1) get Authorities, a list of permissions, usually a set of strings representing permissions;
2) getCredentials, password, will be removed after authentication to ensure security;
3) getDetails, the detailed parameters of the request;
4) getPrincipal, the core identity information, generally returns to the implementation class of UserDetails.

3),UserDetails

It encapsulates the user's detailed information.

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    String getPassword();
    String getUsername();
    boolean isAccountNonExpired();
    boolean isAccountNonLocked();
    boolean isCredentialsNonExpired();
    boolean isEnabled();
}

4),UserDetailsService

Realize the interface, customize user authentication process, usually read the database, compare user login information, complete authentication and authorization.

public interface UserDetailsService {
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

5),AuthenticationManager

Authentication process top-level interface. Spring provides a default implementation, Provider Manager, to customize its own authentication by implementing the Authentication Manager interface.

public interface AuthenticationManager {
    Authentication authenticate(Authentication var1) throws AuthenticationException;
}

Integration with Spring Boot 2

1. Process description

1), three page categories, page1, page2, page3
 2) No unregistered authorization is accessible
 3) Access the specified page according to user rights after login
 4) For unauthorized pages, access returns 403: resources are unavailable

2. Core Dependence

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

3. Core configuration

/**
 * EnableWebSecurity Annotations enable Spring MVC to integrate Spring Security's web security support
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * Permission configuration
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Configuring Interception Rules
        http.authorizeRequests().antMatchers("/").permitAll()
                 .antMatchers("/page1/**").hasRole("LEVEL1")
                 .antMatchers("/page2/**").hasRole("LEVEL2")
                 .antMatchers("/page3/**").hasRole("LEVEL3");
        // Configure login function
        http.formLogin().usernameParameter("user")
                .passwordParameter("pwd")
                .loginPage("/userLogin");
        // Log-off Successful Jump Home Page
        http.logout().logoutSuccessUrl("/");
        //Turn on and remember me
        http.rememberMe().rememberMeParameter("remeber");
    }
    /**
     * Custom Authentication Data Source
     */
    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception{
        builder.userDetailsService(userDetailService())
                .passwordEncoder(passwordEncoder());
    }
    @Bean
    public UserDetailServiceImpl userDetailService (){
        return new UserDetailServiceImpl () ;
    }
    /**
     * Cryptographic Encryption
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /*
     * Hardcoded Several Users
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("spring").password("123456").roles("LEVEL1","LEVEL2")
                .and()
                .withUser("summer").password("123456").roles("LEVEL2","LEVEL3")
                .and()
                .withUser("autumn").password("123456").roles("LEVEL1","LEVEL3");
    }
    */
}

4. Authentication process

@Service
public class UserDetailServiceImpl implements UserDetailsService {
    @Resource
    private UserRoleMapper userRoleMapper ;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // Here you can catch exceptions, use exception mapping, and throw the specified prompt information.
        // Operation of user verification
        // Assuming that the password is 123 for database queries
        String password = "$2a$10$XcigeMfToGQ2bqRToFtUi.sG1V.HhrJV6RBjji1yncXReSNNIPl1K";
        // Assuming that roles are database queries
        List<String> roleList = userRoleMapper.selectByUserName(username) ;
        List<GrantedAuthority> grantedAuthorityList = new ArrayList<>() ;
        /*
         * Spring Boot 2.0 Version trampling
         * ROLE_prefix must be used because hasRole("LEVEL1") will automatically add ROLE_prefix to ROLE_LEVEL1 when judging.
         * If you don't prefix, you will usually get 403 errors
         * When granting permissions to users, database storage must be a complete permission identifier ROLE_LEVEL1
         */
        if (roleList != null && roleList.size()>0){
            for (String role : roleList){
                grantedAuthorityList.add(new SimpleGrantedAuthority(role)) ;
            }
        }
        return new User(username,password,grantedAuthorityList);
    }
}

5. Test Interface

@Controller
public class PageController {
    /**
     * home page
     */
    @RequestMapping("/")
    public String index (){
        return "home" ;
    }
    /**
     * Login page
     */
    @RequestMapping("/userLogin")
    public String loginPage (){
        return "pages/login" ;
    }
    /**
     * page1 Next page
     */
    @PreAuthorize("hasAuthority('LEVEL1')")
    @RequestMapping("/page1/{pageName}")
    public String onePage (@PathVariable("pageName") String pageName){
        return "pages/page1/"+pageName ;
    }
    /**
     * page2 Next page
     */
    @PreAuthorize("hasAuthority('LEVEL2')")
    @RequestMapping("/page2/{pageName}")
    public String twoPage (@PathVariable("pageName") String pageName){
        return "pages/page2/"+pageName ;
    }
    /**
     * page3 Next page
     */
    @PreAuthorize("hasAuthority('LEVEL3')")
    @RequestMapping("/page3/{pageName}")
    public String threePage (@PathVariable("pageName") String pageName){
        return "pages/page3/"+pageName ;
    }
}

6. Login Interface

This corresponds to the Security configuration file.

<div align="center">
    <form th:action="@{/userLogin}" method="post">
        //User name: <input name="user"/><br>
        //Cipher & nbsp; & nbsp; & nbsp; code: < input name = "pwd"> < br />
        <input type="checkbox" name="remeber"> Remember me<br/>
        <input type="submit" value="Login">
    </form>
</div>

3. Source code address

GitHub·address
https://github.com/cicadasmile/middle-ware-parent
GitEE·address
https://gitee.com/cicadasmile/middle-ware-parent

Tags: Programming Spring Database github

Posted on Wed, 04 Sep 2019 08:32:29 -0700 by unixmiah