Spring boot integrates Spring Security

Introduction to spring security

Spring Security is a powerful and highly customizable authentication and access control framework. It is the de facto standard for protecting spring based applications.

Spring Security is a framework that focuses on providing authentication and authorization for Java applications. Like all spring projects, the real strength of Spring Security is that it can be easily extended to meet customization requirements.

features

  • Comprehensive and scalable support for authentication and authorization
  • Prevent fixed session, click hijacking, Cross Site Request Forgery and other attacks
  • Servlet API integration
  • Optional integration with spring Web
  • Much more...

Custom User instance

When the user accesses the interface, query the user's role according to the Authorization carried by the user, and then judge according to the permissions of the set role. If the accessed interface is the interface under the role, release the interface.

 

Project structure

1. maven dependency

 

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

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

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

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

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

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

2. Inherit WebSecurityConfigurerAdapter configuration role permissions

 

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Autowired
    private UserDetailsService userDetailsService;

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


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

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());//Passworldencoder is used to encrypt the password. If the password in user is not encrypted, this method can be omitted. Note: please use the encryption method provided by security.
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()//csrf feature disabled
                .authorizeRequests()//Qualified signature successful request
                .antMatchers("/decision/**","/govern/**","/employee/*").hasAnyRole("EMPLOYEE","ADMIN")//USER or ADMIN permission is required for the interface under decision and govern ment
                .antMatchers("/employee/login").permitAll()///employee/login unlimited
                .antMatchers("/admin/**").hasRole("ADMIN")//Admin permission is required for the interface under admin
                .antMatchers("/oauth/**").permitAll()//Do not block oauth open resources
                .anyRequest().permitAll()//Access is allowed for other unrestricted requests
                .and().anonymous()//Anonymous access is allowed for other requests without configuration permission
                .and().formLogin()//Use spring security default login page
                .and().httpBasic();//Enable http basic authentication

    }

}

Two roles are set here: admin and employee; Admin can access "/ decision / * *", "/ government / * *", "/ employee / *", "/ admin / * *", and employees can access: "/ decision / * *", "/ government / * *", "/ employee / *"; From the perspective of configuration, the admin permission is greater than that of employee.

3. Create user inheritance UserDetailsService

 

@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

        //The generation environment is to query the database to obtain the role of username for subsequent permission judgment (e.g. Zhang San admin)
        //There is no database operation here. Given false data, interested people can make the memory mode.
        if (username.equals("employee")) {
            Employee employee = new Employee();
            employee.setUsername("employee");
            employee.setPassword("123456");
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_EMPLOYEE");
            grantedAuthorities.add(grantedAuthority);
            //Create a user to judge permissions. Please note that this user name is consistent with the username in the method parameters; BCryptPasswordEncoder is used to demonstrate the use of encryption.
            return new User(employee.getUsername(), new BCryptPasswordEncoder().encode(employee.getPassword()), grantedAuthorities);
        }
        if (username.equals("admin")) {
            Admin admin = new Admin();
            admin.setUsername("admin");
            admin.setPassword("123456");
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
            grantedAuthorities.add(grantedAuthority);
            return new User(admin.getUsername(), new BCryptPasswordEncoder().encode(admin.getPassword()), grantedAuthorities);
        }
        else {
            return null;
        }


    }
}

For convenience, we do not connect to the database here. We use fake data for simulation, and use data to replace the generated environment.

4. Create employee and admin entities

 

public class Admin {

    private String username;

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

public class Employee {
    private String id;
    private String username;
    private String password;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

5. Test the code writing of controller layer

 

@RestController
@RequestMapping("/admin")
public class AdminController {


    @GetMapping("/greeting")
    public String greeting() {
        return "Hello,World!";
    }

    @GetMapping("/login")
    public String login() {

        return "login sucess";
    }
}

@RestController
@RequestMapping("/employee")
public class EmployeeController {


    @GetMapping("/greeting")
    public String greeting() {
        return "Hello,World!";
    }

    @GetMapping("/login")
    public String login() {

        return "login sucess";
    }
}

Final effect

  • Employee access employee interface

  • Employee access administrator interface

  • Administrator access administrator interface

     

  • Administrator access employee interface

Memory based instance

Based on memory, indicating that the User comes from memory; Then abandon User's use of auth inMemoryAuthentication()
Just make changes in the above code

 

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(userDetailsService)
//                .passwordEncoder(passwordEncoder());// Passworldencoder is used to encrypt the password. If the password in user is not encrypted, this method can be omitted. Note: please use the encryption method provided by security.
        auth.inMemoryAuthentication()
                .withUser("admin").password("123456").roles("ADMIN")
                .and()
                .withUser("employee").password("123456").roles("EMPLOYEE");
    }

The effect is the same as the above. It is generally used to write demo s, using memory mode, and the generation environment is not often used

Based on database schema

Principle: let spring security inject datasource, then write sql statements, and let spring security execute sql internally for permission judgment. There is no demo demonstration here.


 

Tags: Java Spring Spring Boot security

Posted by Rose.S on Sun, 01 May 2022 12:00:28 +0300