第三章 SpringBoot项目构建 - 整合Spring Security入门

注:后续项目架构完善后会上传至Git,下一章节将实际介绍项目中的配置使用
学习可参考该网址:https://www.cnblogs.com/lvlaotou/p/18114025

1.概述

Spring Security 是一个强大的框架,用于保护基于 Spring 的应用程序。它提供了全面的认证和授权功能,使得安全机制与应用逻辑相分离。以下是 Spring Security 的基本使用指南,包括如何集成 Spring Security、定义用户角色和权限、以及自定义安全配置。

在 Java 生态中,目前有 Spring Security 和 Apache Shiro 两个安全框架,可以完成认证和授权的功能。

1.1【认证】与【授权】

(1)认证(Authentication)

  • 定义: 验证用户身份的过程,用于确定用户或系统是否是它声称的身份。

  • 目的: 确认一个实体(用户、设备或系统)确实是其声称的身份。通过这个过程,系统可以确保进入的请求者的身份是真实的,并且其具备的身份信息是有效的。

  • 举例: 当你登录电子邮件账户时,输入你的用户名和密码,系统验证这些信息以确认你是该账户的合法用户。这是认证的过程。

(2)授权(Authorization)

  • 定义: 指在认证之后,确定一个经过认证的用户或系统在资源上的访问权限的过程。

  • 目的: 根据用户的权限设置,决定用户是否有权访问特定资源或执行某些操作。它决定了“谁能做什么”。

  • 举例: 登录电子邮件账户后,你可以读取、撰写和删除邮件。这是基于你的授权——因为你是账户的拥有者。而你不能访问其他用户的电子邮件,因为你没有授权。

  • 如何实现:

    • 基于角色的访问控制(RBAC): 根据用户的角色来分配访问权限,例如管理员、编辑者、查看者等。
    • 基于属性的访问控制(ABAC): 使用更细粒度的控制,基于用户属性、环境条件和资源属性来决定访问权限。
    • 访问控制列表(ACL):指定哪些用户或组可以访问特定的资源以及他们的权限(例如,读取、写入、执行)。

(3)【认证】与【授权】的区别

方面认证 (Authentication)授权 (Authorization)
定义验证用户身份的过程确定用户访问权限的过程
问题“你是谁?”“你能做什么?”
目的确保用户是其声称的身份决定用户是否有权访问某些资源或执行特定操作
执行时机认证通常在授权之前执行授权在认证之后执行
示例用户使用用户名和密码登录系统根据用户角色允许访问特定的文件或功能

2.快速入门

2.1 添加依赖

首先,在 pom.xml 中添加 Spring Security 的依赖项:

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

2.2 配置文件

application.yml 中,添加 Spring Security 配置,如下:

server:
  port: 48081
  # Spring Security 配置项,对应 SecurityProperties 配置类
  # `UserDetailsServiceAutoConfiguration` 会基于配置的信息创建一个用户 `User `在内存中。
spring:
  security:
    # 配置默认的 InMemoryUserDetailsManager 的用户账号与密码。
    user:
      name: user # 账号
      password: 123 # 密码
      roles: ADMIN # 拥有角色
  • 默认情况下,Spring Boot UserDetailsServiceAutoConfiguration 自动化配置类,会创建一个内存级别的 InMemoryUserDetailsManager Bean 对象,提供认证的用户信息。
  • 这里 spring.security.user 配置项,UserDetailsServiceAutoConfiguration 会基于配置的信息创建一个用户 User 在内存中。

  • 如果,未添加 spring.security.user 配置项,UserDetailsServiceAutoConfiguration 会自动创建一个用户名为 user ,密码为UUID 随机的用户 User 在内存中。

2.3 简单测试

(1)编写测试Controller

import com.server.pojo.MobileDo;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/admin")
@Validated
public class TestController {

    @GetMapping("/demo")
    public String testDemo() {
        return "测试成功!!";
    }
}

(2)项目启动
项目启动浏览器访问 http://127.0.0.1:48081/admin/demo 接口。因为未登录,所以被 Spring Security 拦截到登录界面(因为我们没有自定义登录界面,所以默认会使用 DefaultLoginPageGeneratingFilter 类,生成以下登录界面)。如下图所示:
在这里插入图片描述
输入我们在「2.2 配置文件」中配置的「user/user」账号,进行登录。登录完成后,因为 Spring Security 会记录被拦截的访问地址,所以浏览器自动动跳转 http://127.0.0.1:48081/admin/demo 接口。访问结果如下图所示:
在这里插入图片描述

3. 进阶使用(Spring Security 3.0及以上)-权限配置

Spring Security 3.0 中要配置 Spring Security 跟以往是有些不同的,比如不在继承WebSecurityConfigurerAdapter

3.1 添加依赖

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    
   <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcprov-jdk15on</artifactId>
       <version>1.70</version>
  </dependency>

3.2 配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableMethodSecurity(securedEnabled = true)
public class SecurityConfig {

    @Bean
    // 配置用户信息
    public UserDetailsService userDetailsService() {
        // 配置两个用户,一个具有 USER 角色,一个具有 ADMIN 角色
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user").password(passwordEncoder().encode("1234")).roles("USER").build());
        manager.createUser(User.withUsername("admin").password(passwordEncoder().encode("123")).roles("ADMIN").build());
        return manager;
    }
    @Bean
    // 配置密码编码器
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    // 配置安全过滤器链
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .authorizeHttpRequests(authz -> authz
                        .requestMatchers("/admin/demo").hasRole("ADMIN") // 只有具有 ADMIN 角色的用户可以访问 /admin 下的资源
                        .requestMatchers("/admin/user").hasRole("USER")   // 只有具有 USER 角色的用户可以访问 /user 下的资源
                        .anyRequest().authenticated()// 其他任何请求都需要认证
                )
                .formLogin(withDefaults()) // 启用默认的表单登录
                .logout(withDefaults()); // 启用默认的注销

        // 认证用户时用户信息加载配置,注入springAuthUserService
        httpSecurity.httpBasic(withDefaults());

        return httpSecurity.build();
    }
}

3.3 简单测试

(1)编写测试Controller

import com.server.pojo.MobileDo;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/admin")
@Validated
public class TestController {


    @PostMapping("/test")
    public String checkService(@Valid @RequestBody MobileDo mobileDo) {
        return "测试成功!!";
    }

    @GetMapping("/demo")
    public String testDemoAdminRole() {
        return "ADMIN测试成功!!";
    }
    
    @GetMapping("/user")
    public String testDemoUserRole() {
        return "USER测试成功!!";
    }
    
    @GetMapping("/other")
    public String testDemoOtherRole() {
        return "other测试成功!!";
    }
}

(2)项目启动
项目启动浏览器访问 http://127.0.0.1:48081/admin/demo 接口。因为未登录,所以被 Spring Security 拦截到登录界面,使用USER角色的用户登录。如下图所示:
在这里插入图片描述
输入我们在「3.2 配置类」中配置的「user/1234」账号,进行登录。登录完成后,因为 Spring Security 会记录被拦截的访问地址,以及会判断该角色是否拥有该权限,因为user用户没有该缺陷,所以访问结果如下图所示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值