Learning and using spring security

Reference link: spring security - Basic Introduction (I): https://blog.csdn.net/qq_22172133/article/details/86503223
Take you to Spring Security!: https://www.cnblogs.com/lenve/p/11242055.html

1 Introduction

The core functions of spring security mainly include:

Certification (who are you)
Authorization (what can you do)
Attack protection (against identity forgery)

Its core is a set of filter chains, which will be automatically configured after the project is started. The core is the Basic Authentication Filter, which is used to authenticate the user's identity. A filter in spring security handles an authentication method.

In spring, the application configuration file is used for login interception and other security access, which requires a lot of configuration writing. It is simpler to use springBoot+springSecurity.

2 use

2.1 dependency

Spring Security dependency in pom.xml:

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

2.2 detailed explanation of examples of inheriting WebSecurityConfigurerAdapter

Example 1:
The WebSecurityConfig class uses the @ EnableWebSecurity annotation to enable the Web security support of Spring Security and provide Spring MVC integration. It also extends the WebSecurityConfigurerAdapter and covers some methods to set up some details of Web security configuration.
The configure(HttpSecurity) method defines which URL paths should be protected and which should not. Specifically, the "/" and "/ home" paths are configured to require no authentication. All other paths must be authenticated.
When users successfully log in, they will be redirected to the previously requested page that requires authentication. There is a custom / login page specified by loginPage(), which everyone can view.
For the configureGlobal(AuthenticationManagerBuilder) method, it sets a single user in memory. The user name is "user", the password is "password", and the role is "user".

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
            		//Define the login page. When you are not logged in, you will automatically jump to the page when you access an interface that can only be accessed after logging in
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }
‚Äč//For the configureGlobal(AuthenticationManagerBuilder) method, it sets a single user in memory.
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    //Configuring user names and passwords in Java code
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
}

Example 2

/*The @ EnableWebSecurity annotation is used to enable Spring Security's Web security support and provide Spring MVC integration.
It also extends the WebSecurityConfigurerAdapter and covers some methods to set up some details of Web security configuration.*/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;
    @Resource
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * Resolve failure to inject AuthenticationManager directly
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    /* configure(HttpSecurity)Method defines which URL paths should be protected and which should not.
    Specifically,
    .antMatchers("/login").anonymous() Allow anonymous access
    .antMatchers("/getKey","/**").permitAll()The path in is configured to require no authentication.
    .anyRequest().authenticated() All other paths must be authenticated.*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Based on token distributed authentication, session is not required
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                // Configure permissions
                .authorizeRequests()
                // Login verification code CaptchaImage allows anonymous access
                .antMatchers("/login").anonymous()
                
                .antMatchers("/getKey","/**").permitAll()/*permitAll()Allow all?*/
                // All requests except the above require authentication
                
                .anyRequest().authenticated()
                .and()
                // Allow cross domain access to the corsConfigurationSource equivalent in the config class
                .cors()
                .and()
                // CRSF is disabled because session is not used. Cross site csrf attack defense is disabled. Otherwise, login cannot succeed
                .csrf().disable();

        // Exit function
        http.logout().logoutUrl("/logout");
        // Add JWT filter
        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }
//For the configure(AuthenticationManagerBuilder auth) method, it sets a single user in memory.
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
}

JWT filter

Example 3:
The user name and password can be configured in the Java code. First, we need to create a Spring Security configuration class, which is integrated from the WebSecurityConfigurerAdapter class, as follows:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //The following two lines of configuration indicate that two users are configured in memory
        auth.inMemoryAuthentication()
                .withUser("javaboy").roles("admin").password("$2a$10$OR3VSksVAmCzc.7WeaRPR.t0wyCsIj24k0Bne8iKWV1o.V9wsP8Xe")
                .and()
                .withUser("lisi").roles("user").password("$2a$10$p1H8iWa8I4.CA.7Z8bwLjes91ZpY.rYREGHQEInNtAp4NzL6PLKxi");
    }
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Here, we configure two users in the configure method. The user's password is an encrypted string (the plaintext is 123). Starting from spring 5, it is mandatory to encrypt the password. If you don't want to encrypt, you can use an expired PasswordEncoder instance noopppasswordencoder, but it's not recommended. After all, it's not safe.

BCryptPasswordEncoder password encoding tool is provided in Spring Security. It is very convenient to encrypt and salt passwords. The results of encrypting the same plaintext are always different, so users do not need to save additional salt fields, which is much more convenient than Shiro.

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    VerifyCodeFilter verifyCodeFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
        http
        .authorizeRequests()//Turn on login configuration
        .antMatchers("/hello").hasRole("admin")//Indicates that to access the / hello interface, you need to have the admin role
        .anyRequest().authenticated()//Represents the remaining interfaces, which can be accessed after login
        .and()
        .formLogin()
        //Define the login page. When you are not logged in, you will automatically jump to the page when you access an interface that can only be accessed after logging in
        .loginPage("/login_p")
        //Login processing interface
        .loginProcessingUrl("/doLogin")
        //Defines the key of the user name when logging in. The default is username
        .usernameParameter("uname")
        //Defines the key of the user's password when logging in. The default is password
        .passwordParameter("passwd")
        //Processor successfully logged in
        .successHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("success");
                    out.flush();
                }
            })
            .failureHandler(new AuthenticationFailureHandler() {
                @Override
                public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("fail");
                    out.flush();
                }
            })
            .permitAll()//All interfaces related to form login are directly through
            .and()
            .logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new LogoutSuccessHandler() {
                @Override
                public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("logout success");
                    out.flush();
                }
            })
            .permitAll()
            .and()
            .httpBasic()
            .and()
            .csrf().disable();
    }
}

We can configure the callback of successful login in the successHandler method. If the front and back ends are separated, we can return JSON after successful login. Similarly, the callback of failed login is configured in the failureHandler method, and the callback of successful logout is configured in the logoutSuccessHandler method.

2.3 ignore interception

If a request address does not need to be intercepted, it can be implemented in two ways:

Set anonymous access for this address
 Directly filter out the address, that is, the address does not go Spring Security Filter chain

The second scheme is recommended. The configuration is as follows:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/vercode");
    }
}

Tags: Spring security Web Security

Posted on Fri, 05 Nov 2021 01:21:58 -0400 by darga333