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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
密钥管理服务KMS,1000个密钥,100个凭据,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站也叫极客李华。大家喜欢也可以关注一下

相关文章
|
设计模式 前端开发 JavaScript
【SpringMVC】工作流程及入门案例
【SpringMVC】工作流程及入门案例
65 0
|
7月前
|
存储 前端开发 Java
Spring第三课,Lombok工具包下载,对应图书管理系统列表和登录界面的后端代码,分层思想
Spring第三课,Lombok工具包下载,对应图书管理系统列表和登录界面的后端代码,分层思想
|
8月前
|
JSON 前端开发 Java
SpringMVC概述、入门案例及工作流程
SpringMVC概述、入门案例及工作流程
38 0
|
存储 前端开发 Java
如何实现自定义MVC框架(秘籍上)
如何实现自定义MVC框架(秘籍上)
66 0
|
前端开发 Java 数据库
手把手教你使用Spring Boot从零开始制作用户注册登录功能
手把手教你使用Spring Boot从零开始制作用户注册登录功能
5398 1
手把手教你使用Spring Boot从零开始制作用户注册登录功能
|
存储 SQL 数据库
SpringSecurity基础-记住我功能实现
Remember me(记住我)记住我,当用户发起登录勾选了记住我,在一定的时间内再次访问该网站会默认登录成功,即使浏览器退出重新打开也是如此,这个功能需要借助浏览器的cookie实现,具体流程如下
103 0
|
存储 SQL 数据库
七.SpringSecurity基础-记住我功能实现
SpringSecurity基础-记住我功能实现
|
算法 Java 数据库
【Spring】简单的登录案例和配套知识
1. 演示一下 Spring 管理类的模式 2. 用户登录案例 2.1 准备的对象和其功能 2.1.1 User 2.1.2 UserController 2.1.3 UserService 2.1.4 UserDao 2.1.5 AppConfig 2.1.6 DemoApplication 2.2 各对象之间的依赖关系 2.3 IOC 带来的一个好处 3. Spring 中的日志打印 3.1 Spring 官方提供的方式 3.2 lombok 提供的方法 3.2 日志打印级别 3.3 修改当前日志级别
113 0
|
XML 数据安全/隐私保护 数据格式
WEB核心【案例:用户登录(进阶-)】第五章
目录1,需求2,分析2.1:关键点2.2:步骤3,代码实现3.1:User3.2:login.html3.3:LoginServlet3.4:LoginService3.5:LoginDao1,需求若用户名和密码正确,判定为登录成功,则控制台输出登录成功;若用户名或密码错误,判定为登录失败,则控制台输出登录失败;2,分析2.1:关键点method="post"
WEB核心【案例:用户登录(进阶-)】第五章
|
Java Spring
Spring 源码学习(七)扩展功能 下篇(一)
在前面的 Spring 源码学习系列的文章中,深入分析和学习了 BeanFactoryPostProcessor ,主体是 BeanFactory 的后处理器,这次来学习主体是 Bean 的后处理器:BeanPostProcessor。
Spring 源码学习(七)扩展功能 下篇(一)