【Spring Security】003-Spring Security web权限方案(1):用户认证

绝地灬酷狼 2023-10-05 16:31 29阅读 0赞

目录

一、用户认证

1、设置登录系统的账号、密码

方式一:通过配置文件

方式二:通过配置类

方式三:自定义编写实现类(常用)

2、通过查询数据库完成登录认证

技术点:

第一步:引入MybatisPlus相关依赖

第二步:创建数据库和数据库表

第三步:创建实体类

第四步:创建mapper,并创建UsersMapper接口

第五步:在MyUserDetailsService中调用mapper里面的方法,通过查询数据库进行用户认证

第六步:在启动类(或者配置类)添加@MapperScan注解

第七步:在配置文件application.properties中配置数据库

第八步:访问测试

3、自定义用户登录页面

第一步:修改配置类MySecurityConfig

第二步:创建login.html页面

第三步:在TestController添加index

第四步:访问测试


一、用户认证

1、设置登录系统的账号、密码

方式一:通过配置文件

在 application.properties里面进行配置:

  1. server.port=8111
  2. spring.security.user.name=zibo
  3. spring.security.user.password=123456

方式二:通过配置类

代码演示:

  1. package com.zibo.studyspringsecurity.config;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  4. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  5. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  6. @Configuration
  7. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  8. @Override
  9. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  10. // 对密码进行加密
  11. String password = new BCryptPasswordEncoder().encode("123456");
  12. // 设置账号和密码以及角色
  13. auth.inMemoryAuthentication().withUser("zibo").password(password).roles("admin");
  14. }
  15. }

访问测试:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70

错误解决(修改配置类):

  1. package com.zibo.studyspringsecurity.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  5. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  6. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  7. import org.springframework.security.crypto.password.PasswordEncoder;
  8. @Configuration
  9. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  10. @Override
  11. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  12. // 对密码进行加密
  13. String password = new BCryptPasswordEncoder().encode("123456");
  14. // 设置账号和密码以及角色
  15. auth.inMemoryAuthentication().withUser("zibo").password(password).roles("admin");
  16. }
  17. // 注入 PasswordEncoder 类到 spring 容器中
  18. @Bean
  19. public PasswordEncoder passwordEncoder(){
  20. return new BCryptPasswordEncoder();
  21. }
  22. }

再次访问测试:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70 1

方式三:自定义编写实现类(常用)

概述:

前面的两种方法都不常用,实际项目中肯定是从数据库查询账号和密码;

步骤:

第一步:创建配置类,设置使用哪个userDetailsService实现类;

第二步:编写实现类,返回User对象,User对象有用户名、密码以及操作权限;

第一步代码演示:

  1. package com.zibo.studyspringsecurity.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  6. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  7. import org.springframework.security.core.userdetails.UserDetailsService;
  8. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  9. import org.springframework.security.crypto.password.PasswordEncoder;
  10. @Configuration
  11. public class MySecurityConfig extends WebSecurityConfigurerAdapter {
  12. @Autowired
  13. private UserDetailsService userDetailsService;
  14. @Override
  15. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  16. auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  17. }
  18. // 注入 PasswordEncoder 类到 spring 容器中
  19. @Bean
  20. public PasswordEncoder passwordEncoder(){
  21. return new BCryptPasswordEncoder();
  22. }
  23. }

第二步代码演示:

  1. package com.zibo.studyspringsecurity.service;
  2. import org.springframework.security.core.GrantedAuthority;
  3. import org.springframework.security.core.authority.AuthorityUtils;
  4. import org.springframework.security.core.userdetails.User;
  5. import org.springframework.security.core.userdetails.UserDetails;
  6. import org.springframework.security.core.userdetails.UserDetailsService;
  7. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  8. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  9. import org.springframework.stereotype.Service;
  10. import java.util.List;
  11. @Service("userDetailsService")
  12. public class MyUserDetailsService implements UserDetailsService {
  13. @Override
  14. public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
  15. // 此处仅作演示,实际项目中肯定是从数据库查询的
  16. // 上面的参数String s是表单提取的用户名,我们可以通过用户名去数据库查数据
  17. // 查到了返回,查不到就进行抛出异常或者进行页面跳转或者提示等操作
  18. // 咱们在这里打印一下s看一下
  19. System.out.println("表单提交的用户名是:" + s);
  20. // 手动创建一个Collection<? extends GrantedAuthority> authorities 权限集合
  21. // 实际项目中是从数据库查询的
  22. List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
  23. return new User("zibo",new BCryptPasswordEncoder().encode("123456"),auths); // 此处的auths不允许为空
  24. }
  25. }

访问测试:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70 2

2、通过查询数据库完成登录认证

技术点:

整合MybatisPlus完成查询数据库的操作;

第一步:引入MybatisPlus相关依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.2.1.RELEASE</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.zibo</groupId>
  12. <artifactId>studyspringsecurity</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>studyspringsecurity</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>1.8</java.version>
  18. </properties>
  19. <dependencies>
  20. <!--改成web工程-->
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-web</artifactId>
  24. </dependency>
  25. <!--添加spring-security依赖-->
  26. <dependency>
  27. <groupId>org.springframework.boot</groupId>
  28. <artifactId>spring-boot-starter-security</artifactId>
  29. </dependency>
  30. <!--mybatis-plus-->
  31. <dependency>
  32. <groupId>com.baomidou</groupId>
  33. <artifactId>mybatis-plus-boot-starter</artifactId>
  34. <version>3.0.5</version>
  35. </dependency>
  36. <!--mysql-->
  37. <dependency>
  38. <groupId>mysql</groupId>
  39. <artifactId>mysql-connector-java</artifactId>
  40. </dependency>
  41. <!--lombok 用来简化实体类-->
  42. <dependency>
  43. <groupId>org.projectlombok</groupId>
  44. <artifactId>lombok</artifactId>
  45. </dependency>
  46. <dependency>
  47. <groupId>org.springframework.boot</groupId>
  48. <artifactId>spring-boot-starter-test</artifactId>
  49. <scope>test</scope>
  50. </dependency>
  51. </dependencies>
  52. <build>
  53. <plugins>
  54. <plugin>
  55. <groupId>org.springframework.boot</groupId>
  56. <artifactId>spring-boot-maven-plugin</artifactId>
  57. </plugin>
  58. </plugins>
  59. </build>
  60. </project>

第二步:创建数据库和数据库表

(下面一些数据库表是以后需要用到的,现在此统一创建出来)

创建数据库:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70 3

创建用户表:

  1. CREATE TABLE users ( id BIGINT PRIMARY KEY auto_increment, username VARCHAR ( 20 ) UNIQUE NOT NULL, PASSWORD VARCHAR ( 100 ) );

添加用户数据:

  1. INSERT INTO users
  2. VALUES
  3. ( 1, '张三', '123456' );
  4. INSERT INTO users
  5. VALUES
  6. ( 2, '李四', '123456' );

创建角色表:

  1. CREATE TABLE role ( id BIGINT PRIMARY KEY auto_increment, NAME VARCHAR ( 20 ) );

插入角色数据:

  1. insert into role values(1,'管理员');
  2. insert into role values(2,'普通用户');

创建用户_角色表:

  1. CREATE TABLE role_user ( uid BIGINT, rid BIGINT );

插入用户_角色数据:

  1. insert into role_user values(1,1);
  2. insert into role_user values(2,2);

创建菜单表:

  1. CREATE TABLE menu ( id BIGINT PRIMARY KEY auto_increment, NAME VARCHAR ( 20 ), url VARCHAR ( 100 ), parentid BIGINT, permission VARCHAR ( 20 ) );

插入菜单数据:

  1. insert into menu values(1,'系统管理','',0,'menu:system');
  2. insert into menu values(2,'用户管理','',0,'menu:user');

创建菜单_角色表:

  1. CREATE TABLE role_menu ( mid BIGINT, rid BIGINT );

插入菜单_角色数据:

  1. insert into role_menu values(1,1);
  2. insert into role_menu values(2,1);
  3. insert into role_menu values(2,2);

第三步:创建实体类

创建entity包,并创建Users实体类:

  1. package com.zibo.studyspringsecurity.entity;
  2. import lombok.Data;
  3. @Data
  4. public class Users {
  5. private Integer id;
  6. private String username;
  7. private String password;
  8. }

第四步:创建mapper,并创建UsersMapper接口

  1. package com.zibo.studyspringsecurity.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.zibo.studyspringsecurity.entity.Users;
  4. import org.springframework.stereotype.Repository;
  5. @Repository // 不加会提示错误,但可以运行
  6. public interface UsersMapper extends BaseMapper<Users> {
  7. }

第五步:在MyUserDetailsService中调用mapper里面的方法,通过查询数据库进行用户认证

  1. package com.zibo.studyspringsecurity.service;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.zibo.studyspringsecurity.entity.Users;
  4. import com.zibo.studyspringsecurity.mapper.UsersMapper;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.security.core.GrantedAuthority;
  7. import org.springframework.security.core.authority.AuthorityUtils;
  8. import org.springframework.security.core.userdetails.User;
  9. import org.springframework.security.core.userdetails.UserDetails;
  10. import org.springframework.security.core.userdetails.UserDetailsService;
  11. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  12. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  13. import org.springframework.stereotype.Service;
  14. import java.util.List;
  15. @Service("userDetailsService")
  16. public class MyUserDetailsService implements UserDetailsService {
  17. @Autowired
  18. private UsersMapper usersMapper;
  19. @Override
  20. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  21. // 调用usersMapper方法,根据用户名查询数据库
  22. QueryWrapper<Users> wrapper = new QueryWrapper<>();
  23. // 根据用户名查询
  24. wrapper.eq("username",username);
  25. Users users = usersMapper.selectOne(wrapper);
  26. if(users==null){ // 数据库里面没有此用户名,认证失败
  27. throw new UsernameNotFoundException("用户名不存在!");
  28. }
  29. // 手动创建一个Collection<? extends GrantedAuthority> authorities 角色权限集合
  30. // 实际项目中是从数据库查询的
  31. List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
  32. // 返回从数据库中查询到的账号、密码和角色信息
  33. return new User(users.getUsername(),new BCryptPasswordEncoder().encode(users.getPassword()),auths);
  34. }
  35. }

第六步:在启动类(或者配置类)添加@MapperScan注解

  1. package com.zibo.studyspringsecurity;
  2. import org.mybatis.spring.annotation.MapperScan;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. @SpringBootApplication
  6. @MapperScan("com.zibo.studyspringsecurity.mapper")
  7. public class StudyspringsecurityApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(StudyspringsecurityApplication.class, args);
  10. }
  11. }

第七步:在配置文件application.properties中配置数据库

  1. server.port=8111
  2. # 设置security登录的账号密码
  3. # spring.security.user.name=zibo
  4. # spring.security.user.password=123456
  5. # mysql 数据库连接
  6. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  7. spring.datasource.url=jdbc:mysql://localhost:3306/spring_security?serverTimezone=GMT%2B8
  8. spring.datasource.username=root
  9. spring.datasource.password=root

第八步:访问测试

用户名:张三;密码:123456;

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70 4

3、自定义用户登录页面

第一步:修改配置类MySecurityConfig

  1. package com.zibo.studyspringsecurity.config;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  6. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  7. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  8. import org.springframework.security.core.userdetails.UserDetailsService;
  9. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  10. import org.springframework.security.crypto.password.PasswordEncoder;
  11. @Configuration
  12. public class MySecurityConfig extends WebSecurityConfigurerAdapter {
  13. @Autowired
  14. private UserDetailsService userDetailsService;
  15. @Override
  16. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  17. auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  18. }
  19. // 注入 PasswordEncoder 类到 spring 容器中
  20. @Bean
  21. public PasswordEncoder passwordEncoder(){
  22. return new BCryptPasswordEncoder();
  23. }
  24. @Override
  25. protected void configure(HttpSecurity http) throws Exception {
  26. http.formLogin() // 自定义自己编写的登录页面
  27. // 登录页面设置
  28. .loginPage("/login.html")
  29. // 登录访问的路径,提交到的controller,不需要自己写
  30. .loginProcessingUrl("/user/login")
  31. // 登陆成功之后要跳转到的路径
  32. .defaultSuccessUrl("/test/index").permitAll()
  33. // 设置哪些路径不需要登陆就可以访问
  34. .and().authorizeRequests().antMatchers("/","/test/hello","/user/login").permitAll()
  35. .anyRequest().authenticated()
  36. .and().csrf().disable(); // 关闭csrf防护
  37. }
  38. }

第二步:创建login.html页面

在resources目录下创建static目录,并创建login.html,name必须是username和password;

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <form method="post" action="/user/login">
  9. 用户名:<input type="text" name="username"/>
  10. 密码:<input type="text" name="password"/>
  11. <input type="submit" value="登录"/>
  12. </form>
  13. </body>
  14. </html>

第三步:在TestController添加index

  1. package com.zibo.studyspringsecurity.controller;
  2. import org.springframework.web.bind.annotation.GetMapping;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. @RestController
  6. @RequestMapping("/test")
  7. public class TestController {
  8. @GetMapping("/hello")
  9. public String hello(){
  10. return "Hello Spring Security!";
  11. }
  12. @GetMapping("/index")
  13. public String index(){
  14. return "登录成功!";
  15. }
  16. }

第四步:访问测试

访问http://localhost:8111/test/hello

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70 5

访问http://localhost:8111/test/index

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70 6

登录测试:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI5Njg5MzQz_size_16_color_FFFFFF_t_70 7

发表评论

表情:
评论列表 (有 0 条评论,29人围观)

还没有评论,来说两句吧...

相关阅读