Spring Security dry goods: how to implement different security policies for different interfaces

Keywords: Java Spring FreeMarker Session

1. Preface

Welcome to Read Spring Security Actual Dry Goods Series articles.Recently, a small development partner asked an interesting question.He is working on a project that involves two styles, one is to interface applets and use stateless JWT Token securely, the other is to manage the backend using Freemarker, the Session mechanism that does not separate the front and back ends.What should I do with Spring Security?

2. Solutions

We can inherit many times WebSecurityConfigurerAdapter Build multiple HttpSecurity.The HttpSecurity object tells us how to authenticate a user, how to control access, what policies to take, and so on.

If you've seen the previous tutorials, this is how we configured them:

/**
 * Single Policy Configuration
 *
 * @author felord.cn
 * @see org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration
 * @since 14 :58 2019/10/15
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
@EnableWebSecurity
@ConditionalOnClass(WebSecurityConfigurerAdapter.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class CustomSpringBootWebSecurityConfiguration {
    
    /**
     * The type Default configurer adapter.
     */
    @Configuration
    @Order(SecurityProperties.BASIC_AUTH_ORDER)
    static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            super.configure(auth);
        }

        @Override
        public void configure(WebSecurity web) {
            super.configure(web);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // Configure httpSecurity

        }
    }
}

The above configuration has an HttpSecurity, and as we did, we added a subclass of WebSecurityConfigurerAdapter to configure another HttpSecurity.There are many problems to be solved.

2.1 How to route different security configurations

After configuring two HttpSecurities, how does the program make the applet interface and the background interface correspond to HttpSecurity?

HttpSecurity.antMatcher(String antPattern)It can provide a filtering mechanism.For example, we configure:

     @Override
        protected void configure(HttpSecurity http) throws Exception {
            // Configure httpSecurity
            http.antMatcher("/admin/v1");

        }

The HttpSecurity will then only be available to all URLs starting with/admin/v1.This requires us to specify a uniform URL prefix for different clients.

To mention one thing or the other, HttpSecurity provides functionality that can be personalized.Such as login mode, role system, etc.

2.2 How to specify the default HttpSecurity

We can specify a priority by using the @Order annotation on the WebSecurityConfigurerAdapter implementation. The higher the number, the lower the priority. No @Order annotation will give the lowest priority.

2.3 How to configure different UserDetailsService

In many cases, we want full isolation between normal and administrative users, so we need multiple UserDetailsServices. You can configure the UserDetailsService by setting AuthenticationManagerBuilder specifically in the following ways, as well as by configuring different password policies.

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setUserDetailsService(new UserDetailsService() {
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            // Self-realization
            return  null ;
        }
    });
    // You can also design specific password policies
    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder);
    auth.authenticationProvider(daoAuthenticationProvider);
}

2.4 Final configuration template

After resolving these issues, we have a basic understanding of how to implement multiple security policies in an application.The configuration template is as follows:

/**
 * Multiple Policy Configurations
 *
 * @author felord.cn
 * @see org.springframework.boot.autoconfigure.security.servlet.SpringBootWebSecurityConfiguration
 * @since 14 :58 2019/10/15
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
@EnableWebSecurity
@ConditionalOnClass(WebSecurityConfigurerAdapter.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class CustomSpringBootWebSecurityConfiguration {

    /**
     * Background interface security policy. Default configuration
     */
    @Configuration
    @Order(1)
    static class AdminConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
            //User Details Service Personalization
            daoAuthenticationProvider.setUserDetailsService(new UserDetailsService() {
                @Override
                public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                    // Self-realization
                    return null;
                }
            });
            // You can also design specific password policies
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder);
            auth.authenticationProvider(daoAuthenticationProvider);
        }

        @Override
        public void configure(WebSecurity web) {
            super.configure(web);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // Customize to your needs
            http.antMatcher("/admin/v1")
                    .sessionManagement(Customizer.withDefaults())
                    .formLogin(Customizer.withDefaults());


        }
    }

    /**
     * app Interface security policy. No {@link Order} comment has lower priority than above
     */
    @Configuration
    static class AppConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
            //User Details Service Personalization
            daoAuthenticationProvider.setUserDetailsService(new UserDetailsService() {
                @Override
                public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                    // Self-realization
                    return null;
                }
            });
            // You can also design specific password policies
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder);
            auth.authenticationProvider(daoAuthenticationProvider);
        }

        @Override
        public void configure(WebSecurity web) {
            super.configure(web);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // Customize to your needs
            http.antMatcher("/app/v1")
                    .sessionManagement(Customizer.withDefaults())
                    .formLogin(Customizer.withDefaults());


        }
    }
}

3. Summary

Today we have solved how to adopt different security strategies for different types of interfaces. We hope it will be useful to you. If you have any problems, you can leave a message.Pay more attention: Small Fatty Man, Mainong, more dry goods.

Focus on Public Number: Felordcn for more information

Personal blog:https://felord.cn

Posted by mazen on Wed, 10 Jun 2020 19:21:26 -0700