【WEEK12】 【DAY4】Building Spring Security Environment Part One【English Version】

2024.5.16 Thursday

14. Building SpringSecurity Environment

14.1. Introduction to Security

14.1.1. In web development, security has always been a very important aspect. Although security is a non-functional requirement of the application, it should be considered from the beginning of application development. If security issues are only considered in the later stages of application development, it may lead to a dilemma: on the one hand, the application has serious security vulnerabilities, cannot meet user requirements, and may result in attackers stealing user’s private data; on the other hand, the basic architecture of the application has been determined, fixing security vulnerabilities may require significant architectural adjustments, thus requiring more development time, affecting the application’s release process. Therefore, security-related factors should be considered from the first day of application development and throughout the entire development process.
14.1.2. There are well-known frameworks on the market: Shiro, Spring Security!
14.1.3. Here it needs to be explained that the emergence of each framework is to solve a certain problem, so what problem does the Spring Security framework solve?
14.1.4. Official website (https://spring.io/projects/spring-security):
(Chinese version: https://springdoc.cn/spring-security/)
14.1.4.1. Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
14.1.4.2. Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements.
14.1.5. Spring Security is a powerful and highly customizable authentication and access control framework. It is the de-facto standard for securing Spring-based applications.
14.1.6. Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements.
14.1.7. From the introduction on the official website, it can be known that this is an authorization framework. How did we control permissions when we didn’t use a framework in previous projects? Permissions are generally subdivided into functional permissions, access permissions, and menu permissions. The code would be written very cumbersome and redundant.
14.1.8. How to solve the problem of cumbersome and redundant permission code written before? Some mainstream frameworks have emerged, and Spring Security is one of them.
14.1.9. Spring is a very popular and successful Java application development framework. Based on the Spring framework, Spring Security provides a complete solution for web application security. Generally speaking, the security of web applications includes two parts: user authentication and user authorization. User authentication refers to verifying whether a user is a legitimate subject in the system, that is, whether the user can access the system. User authentication generally requires the user to provide a username and password. The system completes the authentication process by verifying the username and password. User authorization refers to verifying whether a user has permission to perform a certain operation. In a system, different users have different permissions. For example, for a file, some users can only read it, while others can modify it. Generally speaking, the system will assign different roles to different users, and each role corresponds to a series of permissions.
14.1.10. For the two application scenarios mentioned above, Spring Security framework has good support. In terms of user authentication, the Spring Security framework supports mainstream authentication methods, including HTTP basic authentication, HTTP form authentication, HTTP digest authentication, OpenID, and LDAP, etc. In terms of user authorization, Spring Security provides role-based access control and access control lists (ACLs), which can control domain objects in the application in a fine-grained manner.

14.2. Testing

14.2.1. Create a new project named springboot-06-security

Create a new project
Create a new project

Add Maven support (click the plus sign in Project Structure->Modules to add the corresponding project), as usual, modify Maven, JDK, and Java versions in settings, JDK, and Java versions in Project Structure. Modify the Springframework version to 2.7.13 in pom.xml, add Thymeleaf dependency in pom.xml, and reload Maven.

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

Delete redundant files.

14.2.2. Import Resources

Import Resources
Resources have been uploaded to: https://download.csdn.net/download/2401_83329143/89316854

14.2.3. Create a new controller folder

14.2.3.1. Create a new file named RouterController.java

Create RouterController.java

package com.P34.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class RouterController {

    @RequestMapping({"/", "/index"})
    public String index(){
        return "index";
    }

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "views/login";
    }

    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id") int id){
        return "views/level1/"+id;
    }

    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id") int id){
        return "views/level2/"+id;
    }

    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id") int id){
        return "views/level3/"+id;
    }

}
14.2.3.2. Modify application.properties to disable cache
spring.application.name=springboot-06-security
spring.thymeleaf.cache=false
14.2.3.3. Run Springboot06SecurityApplication.java

Access http://localhost:8080/
Access URL
Access URL
在这里插入图片描述

14.3. Understanding Spring Security

Spring Security is a security framework for Spring projects and the default technology choice for the underlying security module of Spring Boot. It enables powerful web security controls with minimal configuration by simply importing the spring-boot-starter-security module.
Remember a few key classes:

  • WebSecurityConfigurerAdapter: Customizes Security strategies.
  • AuthenticationManagerBuilder: Customizes authentication strategies.
  • @EnableWebSecurity: Enables WebSecurity mode.
    The two main goals of Spring Security are “Authentication” and “Authorization” (Access Control).

14.3.1. Authentication

Authentication is about verifying your credentials, such as username/userID and password, to validate your identity. Authentication is typically done with a username and password, sometimes combined with authentication factors.

14.3.2. Authorization

Authorization occurs after the system successfully verifies your identity, ultimately granting you full access to resources (such as information, files, databases, funds, locations, almost anything). This concept is universal, not only present in Spring Security.

14.4. Authentication and Authorization

Currently, our test environment is accessible to any user. Let’s use Spring Security to add authentication and authorization functionality.

14.4.1. Import Spring Security module (pom.xml)

<?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 https://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>2.7.13</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot-06-security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-06-security</name>
    <description>springboot-06-security</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--security-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-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>

14.4.2. Create a new config folder

Create SecurityConfig.java
Create SecurityConfig.java

package com.P34.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

// Implement interceptor functionality using AOP
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // Override methods using alt+insert
    // Method chaining
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Everyone can access the home page, functional pages are only open to authorized users
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
    }
//    public WebSecurityCustomizer webSecurityCustomizer() - New method
}

14.4.3. Restart

Restart
Restart

14.4.4. Modifying SecurityConfig.java

Adding a statement to redirect to the login page if unauthorized

package com.P34.config;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

// Implement interceptor functionality using AOP
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //alt+insert->override methods
    //Method chaining
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Everyone can access the home page, functional pages are only open to authorized users
        // Request authorization rules
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        // Redirect to login page if not authorized
        http.formLogin();
    }
//    public WebSecurityCustomizer webSecurityCustomizer() - New method
}

After restarting, try accessing http://localhost:8080/level1/1 again without permission. Unlike the previous step, this time it doesn’t display error 403; instead, it directly redirects to the login page.
Redirect to login page

14.4.5. Continuing Modification in SecurityConfig.java

package com.P34.config;

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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

// Implement interceptor functionality using AOP
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //alt+insert->override methods
    //Method chaining
    //Authorization
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Everyone can access the home page, functional pages are only open to authorized users
        // Request authorization rules
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        // Redirect to login page if not authorized, can check source code of formLogin for more details
        http.formLogin();
    }
//    public WebSecurityCustomizer webSecurityCustomizer() - New method

    //Authentication
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // Syntax example visible by opening WebSecurityConfigurerAdapter at line 194:
        /**
         * protected void configure(AuthenticationManagerBuilder auth) {
         *     auth
         *     // enable in memory based authentication with a user named
         *     // &quot;user&quot; and &quot;admin&quot;
         *     .inMemoryAuthentication().withUser(&quot;user&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;).and()
         *           .withUser(&quot;admin&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;, &quot;ADMIN&quot;);
         * }
         */
        // These data should theoretically be retrieved from the database
        // Running it shows "There was an unexpected error (type=Internal Server Error, status=500)".
        // The password encoding is missing (There is no PasswordEncoder mapped for the id “null”), so we need to encrypt the "password" in the code
        // Many encryption methods have been added in Spring Security 5.0+: click BCryptPasswordEncoder->PasswordEncoder->click the green "I" on the left sidebar (see image below)
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("Zzz").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
    }
}

PasswordEncoder

14.4.6. Restart

Login and verify the permissions for the three users created.

14.4.6.1. Zzz

Both Level1 and Level2 are accessible.
Access granted for Zzz
Access granted for Zzz
Level3 is not accessible.
Access denied for Zzz

14.4.6.2. Root

Levels 1, 2, and 3 are accessible. The pages are similar to those accessible to Zzz and hence not shown.

14.4.6.3. Guest

Only Level3 is accessible.
Access granted for Guest

Access is denied for Levels 1, 2, and for pages accessible to Zzz, hence not shown.

  • 43
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值