Spring boot integrates Spring Security and uses Demo

Keywords: Java Spring Maven Apache encoding

https://start.spring.io/ generate SpringBoot project

 

The pom file should be me:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.20.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.dreamtech</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>demo</name>
    <description>Demo project for Spring Security</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- stay IDEA If the project fails to run, comment out this item -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

Controller:

package org.dreamtech.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Spring Boot Startup class
 * @author Xu Yiqing
 *
 */
@SpringBootApplication
@RestController
@EnableAutoConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    
    /**
     * Root, accessible to all
     * @return
     */
    @RequestMapping("/")
    public String helloSpringBoot() {
        return "hello spring boot";
    }
    
    /**
     * Can only be accessed after authentication
     * @return
     */
    @RequestMapping("/hello")
    public String helloWorld() {
        return "hello world";
    }
    
    /**
     * It is authenticated and the identity must be ADMIN to access, and it is verified before method execution
     * @return
     */
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping("/role")
    public String role() {
        return "admin auth";
    }

}

 

Spring Security profile:

package org.dreamtech.demo;

import org.springframework.beans.factory.annotation.Autowired;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * Spring Security configuration file
 * @author Xu Yiqing
 *
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserService myUserService;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /* The user name and password can be stored in memory, or can be fetched from the database by using custom Service
        auth.inMemoryAuthentication().withUser("admin").password("12345").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("test").password("test").roles("USER");
        */
        auth.userDetailsService(myUserService).passwordEncoder(new MyPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Configure root path release, other request interception, and logout Release, allow form verification, disable CSRF
        http.authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated().and().logout().permitAll()
                .and().formLogin();
        http.csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // Configuration ignored js,css,images Static file
        web.ignoring().antMatchers("/js/**", "/css/**", "/images/**");
    }

}

 

Custom password encryptor:

package org.dreamtech.demo;

import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Custom password encryptor
 * 
 * @author Xu Yiqing
 *
 */
@SuppressWarnings("deprecation")
public class MyPasswordEncoder implements PasswordEncoder {

    // Salt for encryption
    private static final String SALT = "666";

    /**
     * encryption
     */
    @Override
    public String encode(CharSequence rawPassword) {
        Md5PasswordEncoder encoder = new Md5PasswordEncoder();
        return encoder.encodePassword(rawPassword.toString(), SALT);
    }

    /**
     * matching
     */
    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        Md5PasswordEncoder encoder = new Md5PasswordEncoder();
        return encoder.isPasswordValid(encodedPassword, rawPassword.toString(), SALT);
    }

}

 

Service:

package org.dreamtech.demo;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

/**
 * Custom service
 * @author Xu Yiqing
 *
 */
@Component
public class MyUserService implements UserDetailsService {

    /**
     * Query by user name from DAO layer
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetails userDetails = null;
        // DAO operation ......
        return userDetails;
    }

}

 

The Service layer here is just an example

If you want to see the specific effect, you should use the two lines commented out in configure to test

 

Conclusion:

Advantages of Spring Security: complete functions and high compatibility with Spring

Disadvantages of Spring Security: large system, cumbersome configuration, not intuitive enough

Therefore, in actual development, people usually choose Apache Shiro instead of Spring Security

Posted by jaku78 on Sun, 24 Nov 2019 11:22:30 -0800