SpringSecurity入门案例——基本功能讲解

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SpringSecurity入门案例——基本功能讲解

SpringSecurity入门案例——基本功能讲解

简介:本文讲解,SpringSecurity的快速入门案例,主要讲解基本功能,其他拦截器,与jwt的结合在后面的文章中讲解。

项目代码地址:https://gitee.com/geek-li-hua/code-in-blog.git

项目实现

项目准备

导入依赖

这些是这个项目需要的依赖

  • Spring Boot Starter JDBC
  • Project Lombok
  • MySQL Connector/J
  • mybatis-plus-boot-starter
  • mybatis-plus-generator
  • spring-boot-starter-security
<!-- Spring Boot Starter JDBC -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- Project Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- MySQL Connector/J -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
        <!-- MyBatis Plus Boot Starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!-- MyBatis Plus Generator -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!-- Spring Boot Starter Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
  • 完整的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.15</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springsecurity-back-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springsecurity-back-demo</name>
    <description>springsecurity-back-demo</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot Starter JDBC -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!-- Project Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- MySQL Connector/J -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
        <!-- MyBatis Plus Boot Starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!-- MyBatis Plus Generator -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!-- Spring Boot Starter Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- JJWT API -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.11.2</version>
        </dependency>
        <!-- JJWT Implementation -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.11.2</version>
            <scope>runtime</scope>
        </dependency>
        <!-- JJWT Jackson -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.11.2</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
配置文件
spring.port = 8080
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
springsecurity登录

当我们启动项目的时候,会出现一个密码,这是因为加入了springsecurity的依赖导致的。

当我们通过一个网页,访问其中一个端口时

会发现需要输入账号和密码,其中账号是user,密码是上面生成的,只有登录之后,我们才可以进行相关的调试。

实现加密
  • 我们需要使用到一个类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

  • 我们在测试类中演示它的使用

对密码进行加密

@Test
    void contextLoads() {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        System.out.println(passwordEncoder.encode("123456"));
    }

对于同一字符串,每次加密的结果可能也不一样。

  • 可以通过matchs方法检验,加密之后与之前是否匹配

可以通过结果看出来的是,虽然对于同一密码每次的加密都不一样,但是,都是可以匹配的。

@Test
    void contextLoads() {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        System.out.println(passwordEncoder.encode("123456"));
        System.out.println(passwordEncoder.matches("123456", "$2a$10$9dBGJIqaejarMaPSJZfzZumyyT4gjY8etzgp3warVCJw2GR6USbtC")); // true
        System.out.println(passwordEncoder.encode("123456"));
        System.out.println(passwordEncoder.matches("123456", "$2a$10$WPyb8qBc7DfPSD6l6nVnauiexFQ/MTF6nExLZid4Li5RINhBfr4pC")); // true
        System.out.println(passwordEncoder.encode("123456"));
        System.out.println(passwordEncoder.matches("123456", "$2a$10$U0M5Xap/aKo7ZBLiZEvfluZH8FQT10yD2PwInhyU/7W2bSXNoBcba")); // true
        System.out.println(passwordEncoder.matches("1", "$2a$10$U0M5Xap/aKo7ZBLiZEvfluZH8FQT10yD2PwInhyU/7W2bSXNoBcba")); // false
    }

让SpringSecurity的登录账号和密码与自己的数据中的用户的信息匹配
  • 实现一个UserDetailsServiceImpl类
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 根据用户名查询用户信息
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        // 判断用户是否存在
        if (user == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        return new UserDetailsImpl(user);
    }
}、

  • 再实现一个UserDetailsImpl类,实现UserDetails里面的方法,并且重写,按照我下面的这样
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDetailsImpl implements UserDetails {
    private User user;
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // 返回拥有的权限
        return null;
    }
    @Override
    public String getPassword() {
        // 返回密码
        return user.getPassword();
    }
    @Override
    public String getUsername() {
        // 返回用户名
        return user.getUsername();
    }
    @Override
    public boolean isAccountNonExpired() {
        // 返回账户是否未过期
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        // 返回账户是否未锁定
        return true;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        // 返回凭据是否未过期
        return true;
    }
    @Override
    public boolean isEnabled() {
        // 返回账户是否可用
        return true;
    }
}

  • 当我们上面都配置正确之后,我们再次运行的时候,就不会生成一个随机密码了

  • 配置完上面的之后,我们就可以用数据库里面的账号,进行登录了。
    如果数据库里面存的是没有加密的数据,可以加上{noop},这样就可以不用存密文。

两个用户使用123456都可以登录,第二个用户存储的是123456加密之后的密文

  • 实现下面的方法,特别是addUser的方法,对用户进行添加,以后注册就是这个原理
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    IUserService userService;
    /**
     * 查询所有用户
     */
    @GetMapping("/all/")
    public List<User> getAll() {
        return userService.list();
    }
    /**
     * 查询单个用户
     */
    @GetMapping("/{userId}/")
    public User getUser(@PathVariable int userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",userId);
        return userService.getOne(queryWrapper);
    }
    /**
     * 添加某个用户 直接输入 id name password
     * @param userId
     * @param username
     * @param password
     * @return Add User Sucessfully
     */
    @GetMapping("/add/{userId}/{username}/{password}/")
    public String addUser(
            @PathVariable int userId,
            @PathVariable String username,
            @PathVariable String password) {
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encodedPassword = passwordEncoder.encode(password);
        User user = new User(userId, username, encodedPassword);
        userService.save(user);
        return "Add User Successfully";
    }
    /**
     * 删除某个用户,直接输入 id
     * @param userId
     * @return Delete User Successfully
     */
    @GetMapping("/delete/{userId}/")
    public String deleteUser(@PathVariable int userId) {
        userService.removeById(userId);
        return "Delete User Successfully";
    }
}

如果大家觉得有用的话,可以关注我下面的微信公众号,极客李华,我会在里面更新更多行业资讯,企业面试内容,编程资源,如何写出可以让大厂面试官眼前一亮的简历等内容,让大家更好学习编程,我的抖音,B站也叫极客李华。大家喜欢也可以关注一下

相关文章
|
5月前
|
Java 数据安全/隐私保护 Spring
SpringSecurity6从入门到实战之默认用户的生成流程
该文档介绍了SpringSecurity6中默认用户的生成流程。在`SecurityAutoConfiguration`源码中,通过`SecurityProperties`配置类,系统默认创建了一个名为&quot;user&quot;的用户,其密码是一个随机生成的UUID。这个用户是在没有在`application.properties`中设置相关配置时自动创建的。
|
5月前
|
存储 前端开发 Java
Spring第三课,Lombok工具包下载,对应图书管理系统列表和登录界面的后端代码,分层思想
Spring第三课,Lombok工具包下载,对应图书管理系统列表和登录界面的后端代码,分层思想
|
5月前
|
缓存 安全 Java
【权限管理系统】Spring security(三)---认证过程(原理解析,demo)
【权限管理系统】Spring security(三)---认证过程(原理解析,demo)
|
6月前
|
Java Spring 容器
【二十一】搭建SpringCloud项目五(Hystix)并使用自定义配置
【二十一】搭建SpringCloud项目五(Hystix)并使用自定义配置
57 0
|
6月前
|
安全 Java 容器
SpringBoot - 优雅的实现【业务校验】高级进阶
SpringBoot - 优雅的实现【业务校验】高级进阶
206 0
|
11月前
|
Java 程序员 应用服务中间件
spring框架核心技术讲解(上)--超详细教程加案例分析
spring框架核心技术讲解(上)--超详细教程加案例分析
122 0
|
存储 SQL 数据库
SpringSecurity基础-记住我功能实现
Remember me(记住我)记住我,当用户发起登录勾选了记住我,在一定的时间内再次访问该网站会默认登录成功,即使浏览器退出重新打开也是如此,这个功能需要借助浏览器的cookie实现,具体流程如下
85 0
|
存储 SQL 数据库
七.SpringSecurity基础-记住我功能实现
SpringSecurity基础-记住我功能实现
|
前端开发 NoSQL Java
Spring Boot + vue-element 开发个人博客项目实战教程(二十、登录日志、用户、分类管理页面开发)1
Spring Boot + vue-element 开发个人博客项目实战教程(二十、登录日志、用户、分类管理页面开发)1
153 0
|
Java
《springboot实战》 第十三章 knife4j增强文档
《springboot实战》 第十三章 knife4j增强文档
275 0