目录

一、基于用户的内存认证

 二、基于数据库用户认证

2.1、添加数据库 

2.2、添加相关pom依赖 

2.3、测试实现 

三、添加用户 

四、密码加密 

五、 自定义登录页


一、基于用户的内存认证

@Configuration
//@EnableWebSecurity //开启springSecurity自定义配置(springboot默认开启)
public class MySecurityConfig {
    @Bean
    public UserDetailsService userDetailsService() {
        //创建基于内存的用户信息管理器
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        //创建UserDetails对象,用于管理用户名,密码,角色,权限等
        manager.createUser(User.withDefaultPasswordEncoder().username("user").password("123456").roles("USER").build());
        return manager;
    }
}

 二、基于数据库用户认证

2.1、添加数据库 

#创建数据库
CREATE DATABASE `security-demo`;
#创建表
CREATE TABLE `user`(
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(50) DEFAULT NULL,
  `password` VARCHAR(400) DEFAULT NULL,
  `enabled` BOOLEAN NOT NULL
);
#添加唯一索引
CREATE UNIQUE INDEX `user_name_uindex` ON `user`(`name`);
#添加数据
INSERT INTO `user`(`name`,`password`,`enabled`) VALUES('admin','{bcrypt}$2a$10$FGfmxDS7Vr/xdE4bheKgFOPZjjxn74r7GV17qR0mkG9PZCT/MmmfO',TRUE),
('jack','{bcrypt}$2a$10$FGfmxDS7Vr/xdE4bheKgFOPZjjxn74r7GV17qR0mkG9PZCT/MmmfO',TRUE),
('tom','{bcrypt}$2a$10$FGfmxDS7Vr/xdE4bheKgFOPZjjxn74r7GV17qR0mkG9PZCT/MmmfO',TRUE);

2.2、添加相关pom依赖 

这里要将版本统一否则运行报错

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity6</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.4.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis-spring</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

springboot配置文件

#数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/security-demo
spring.datasource.username=root
spring.datasource.password=123456
#sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

2.3、测试实现 

实现步骤:

1、创建一个DBUserDetailsManagerConfig 类实现UserDetailsManager, UserDetailsPasswordService 接口

2、实现loadUserByUsername()方法

测试代码:

@Data
public class User {
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    private String name;
    private String password;
    private Boolean enabled;
}
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cjc.securitydemo.mapper.UserMapper">

</mapper>
public interface UserService extends IService<User> {
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {

}
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @GetMapping("/getListUser")
    public List<User> getListUser(){
        return userService.list();
    }
}

方式一:使用@Component

@Component
public class DBUserDetailsManagerConfig implements UserDetailsManager, UserDetailsPasswordService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("name",username);
        User user = userMapper.selectOne(userQueryWrapper);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }else {
            Collection<GrantedAuthority> collection = Arrays.asList();
            return new org.springframework.security.core.userdetails.User(
                    user.getName(),
                    user.getPassword(),
                    user.getEnabled(),
                    true,//用户账号是否过期
                    true, //用户凭证是否过期
                    true, //用户是否被锁定
                    collection //权限列表
            );
        }
    }
    @Override
    public UserDetails updatePassword(UserDetails user, String newPassword) {
        return null;
    }

    @Override
    public void createUser(UserDetails user) {

    }

    @Override
    public void updateUser(UserDetails user) {

    }

    @Override
    public void deleteUser(String username) {

    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {

    }

    @Override
    public boolean userExists(String username) {
        return false;
    }

方式二: 不使用@Component

@Bean
  public UserDetailsService dbUserDetailsManagerConfig(){
     return new DBUserDetailsManagerConfig();
  }

三、添加用户 

添加该依赖用于测试

<dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>4.1.0</version>
        </dependency>
 void saveUser(User user);
 @Autowired
    private DBUserDetailsManagerConfig dbUserDetailsManagerConfig;
    @Override
    public void saveUser(User user) {
        dbUserDetailsManagerConfig.createUser(org.springframework.security.core.userdetails.User
                .withDefaultPasswordEncoder()
                .username(user.getName())
                .password(user.getPassword())
                .build());
    }
@Component
public class DBUserDetailsManagerConfig implements UserDetailsManager, UserDetailsPasswordService {
    @Autowired
    private UserMapper userMapper;
    //添加用户信息
    @Override
    public void createUser(UserDetails user) {
        User myUser = new User();
        myUser.setName(user.getUsername());
        myUser.setPassword(user.getPassword());
        myUser.setEnabled(true);
        userMapper.insert(myUser);
    }
}
@PostMapping("/addUser")
    public void addUser(@RequestBody User user){
        userService.saveUser(user);
        System.out.println("添加一次");
    }

四、密码加密 

@Test
    void contextLoads() {
        //工作因子,默认为10,最小4,最大31,防止密码被暴力破解
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(4);
        String encode = bCryptPasswordEncoder.encode("123456");
        System.out.println(encode);
         if (bCryptPasswordEncoder.matches("123456", encode)){
             System.out.println("密码正确");
         }else {
             System.out.println("密码错误");
         }
    }

五、 自定义登录页

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests(
                authorize -> authorize
                        .anyRequest() //对所有请求开启授权保护
                        .authenticated() //已认证的请求会自动授权
               )
                .formLogin(
                        //Customizer.withDefaults()
                        form -> form.loginPage("/login")
                                .permitAll()//无需授权就能访问
                                .usernameParameter("name")
                                .passwordParameter("pass")
                );//使用表单授权方式
                //.httpBasic(Customizer.withDefaults());//使用基本授权方式
        httpSecurity.csrf(csrf -> csrf.disable());//关闭csrf功能
        return httpSecurity.build();
    }
@Controller
public class LoginController {

    @GetMapping("/login")
    public String getLogin(){
        return "login";
    }
}
<html xmlns:th="https://www.thymeleaf.org">
<head>
    <title>登录</title>
</head>
<body>
<h1>登录</h1>
<div th:if="${param.error}">
    错误的用户名或密码
</div>
<form th:action="@{/login}" method="post">
    <div>
        <input type="text" name="name" placeholder="用户名"/>
    </div>
    <div>
        <input type="password" name="pass" placeholder="密码"/>
    </div>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

06-16 14:49