Geeks_Z の Blog Geeks_Z の Blog
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)

Geeks_Z

AI小学生
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)
  • Linux

  • 数据结构与算法

  • 算法设计与分析

  • Java

  • Python

  • 设计模式

  • 计算机网络

  • Spring笔记

  • SpringMVC笔记

  • SpringBoot笔记

  • SpringSecurity

    • SpringSecurity
    • SpringSecurity简介
    • SpringSecurity Web 权限方案
    • 新建 Markdown
    • 新建 Markdown
    • Handler
    • 注解使用
    • CSRF
    • 访问控制
      • anyRequest()
      • antMatchers()
      • regexMatchers()
      • hasAuthority 方法
        • 修改配置类
        • Controller
      • hasAnyAuthority 方法
        • 修改配置类
        • Controller
      • hasRole 方法
        • 底层源码
        • 给用户添加角色
        • 修改配置类
        • Controller
      • hasAnyRole 方法
        • 给用户添加角色:
        • 修改配置类
        • Controller
      • 配置
      • Controller
      • 自定义 403 页面
        • 修改 SecurityConfigTest 配置类
        • unauth.html
  • Elasticsearch笔记

  • RabbitMQ笔记

  • Docker笔记

  • MySQL

  • Redis

  • Mybatis

  • MybatisPlus

  • Nginx

  • Kubernetes笔记

  • Git

  • Software

  • 微服务笔记

  • bug

  • BackEndNotes
  • SpringSecurity
Geeks_Z
2023-09-04
目录

访问控制

anyRequest()

anyRequest() 表示匹配所有的请求,一般情况下此方法都会使用,设置全部内容都需要进行认证

// 推荐将anyRequest()放在最后使用
.anyRequest().authenticated();
1
2

antMatchers()

public C antMatchers(String... antPatterns)
1

参数是可变参数,每个参数都是一个 ant 表达式,用于匹配 URL 规则

规则如下

  • ?:匹配一个字符
  • *:匹配 0 个或多个字符
  • **:匹配 0 个或多个目录

在实际项目中经常需要进行放行所有静态资源,下面演示放行 js 文件夹下所有脚本文件。

.antMatchers("/js/**", "/css/**").permitAll();
1

还有一种配置方式只要是 .js 文件都放行

.antMatchers("/**/*.js").permitAll();
1

regexMatchers()

regexMatchers() 运行我们使用正则表达式匹配路径

public C regexMatchers(String... regexPatterns)
1

放行所有 .png 文件

.regexMatchers(".+[.]png$").permitAll();
1

方法定义

public C regexMatchers(HttpMethod method, String... regexPatterns)
1

允许我们在指定路径的同时指定请求的方式

基于角色或权限进行访问控制

💡 以下修改的配置类是 SecurityConfig

hasAuthority 方法

如果当前的主体具有指定的权限,则返回 true,否则返回 false。

注意:此方法只能设置一个权限,多次设置后面的会覆盖前面的;使用逗号不会进行分割而是看作一个整体。

修改配置类

// 设置指定的请求需要的权限
        http.authorizeRequests()
                .antMatchers("/admin")
                .hasAuthority("admin"); // 如果用户没有admin权限则无法访问
1
2
3
4

Controller

@GetMapping("/admin")
public String admin(){
    return "hello admin";
}
1
2
3
4

hasAnyAuthority 方法

如果当前的主体有任何提供的角色(给定的作为一个逗号分隔的字符串列表)的话,返回 true

注意:只需要拥有指定的权限中的一个权限就行,不需要全部拥有。

修改配置类

// #####设置指定的请求需要的权限, 多个权限之间可以使用逗号分割#####
    http.authorizeRequests()
        .antMatchers("/anyAdmin")
        .hasAnyAuthority("admin", "manager"); // 如果用户拥有admin或者manager权限中的一个就可以访问
1
2
3
4

Controller

@GetMapping("/anyAdmin")
public String anyAdmin(){
    return "hello anyAdmin";
}
1
2
3
4

hasRole 方法

如果用户具备给定角色就允许访问,否则出现 403。 如果当前主体具有指定的角色,则返回 true。

底层源码

private static String hasRole(String role) {
   Assert.notNull(role, "role cannot be null");
   Assert.isTrue(!role.startsWith("ROLE_"),
         () -> "role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
   return "hasRole('ROLE_" + role + "')";
}
1
2
3
4
5
6

可以看到最后返回时会拼接 ROLE_ 前缀,因此我们在给用户设置角色时需要加上这个前缀,与权限进行区分。

给用户添加角色

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    /**
     * 作用: 进行用户名的判断
     * 运行流程: 这个方法会传入一个用户名, 我们可以根据用户名进行查询, 并将查询结果交给SpringSecurity,
     *          SpringSecurity会帮我们进行密码的判断操作, 我们需要负责用户名的判断。
     * 总结: SpringSecurity会根据我们返回的UserDetails对象进行密码的判断, 但是并不会判断用户名,
     *       因此我们需要编写用户名的判断操作
     * @param username 登录时传入的用户名
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 调用userMapper方法, 根据用户名查询数据库
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        // 判断
        if(user == null){
            throw new UsernameNotFoundException("用户不存在");
        }
        // 设置用户拥有的权限, 多个权限之间使用逗号分割
        List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale,ROLE_admin");
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                new BCryptPasswordEncoder().encode(user.getPassword()),
                // BCryptPasswordEncoder在对密码进行对比时, 一定时拿明文和密文进行对别,
                // 所有我们这里进行手动加密,因为我们数据库中存的就是明文,
                // 如果数据库中存的是密文就不需要我们手动进行加密了;
                auths);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

修改配置类

注意配置时是不需要添加 ROLE_,因为上述的底层代码会自动添加与之进行匹配。

// 设置指定的请求需要的角色, 与hasAuthority类似
        http.authorizeRequests()
                .antMatchers("/role")
                .hasRole("sale,admin");
1
2
3
4

Controller

@GetMapping("/role")
    public String role(){
        return "hello role";
    }
1
2
3
4

hasAnyRole 方法

表示用户具备任何一个条件都可以访问。

给用户添加角色:

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    /**
     * 作用: 进行用户名的判断
     * 运行流程: 这个方法会传入一个用户名, 我们可以根据用户名进行查询, 并将查询结果交给SpringSecurity,
     *          SpringSecurity会帮我们进行密码的判断操作, 我们需要负责用户名的判断。
     * 总结: SpringSecurity会根据我们返回的UserDetails对象进行密码的判断, 但是并不会判断用户名,
     *       因此我们需要编写用户名的判断操作
     * @param username 登录时传入的用户名
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 调用userMapper方法, 根据用户名查询数据库
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        // 判断
        if(user == null){
            throw new UsernameNotFoundException("用户不存在");
        }
        // 设置用户拥有的权限, 多个权限之间使用逗号分割
        List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_sale,ROLE_admin");
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                new BCryptPasswordEncoder().encode(user.getPassword()),
                // BCryptPasswordEncoder在对密码进行对比时, 一定时拿明文和密文进行对别,
                // 所有我们这里进行手动加密,因为我们数据库中存的就是明文,
                // 如果数据库中存的是密文就不需要我们手动进行加密了;
                auths);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

修改配置类

// 设置指定的请求需要的角色, 与hasAuthority类似
        http.authorizeRequests()
                .antMatchers("/role")
                .hasRole("sale,admin");
1
2
3
4

Controller

@GetMapping("/anyRole")
    public String anyRole(){
        return "hello anyRole";
    }
1
2
3
4

基于 IP 地址进行访问控制

配置

http.authorizeRequests()
        .antMatchers("/hasIpAddress")
        .hasIpAddress("192.168.200.130");
1
2
3

Controller

@GetMapping("/hasIpAddress")
public String hasIpAddress(){
    return "hello hasIpAddress";
}
1
2
3
4

自定义 403 页面

修改 SecurityConfigTest 配置类

@Override
protected void configure(HttpSecurity http) throws Exception {
	// 自定义403访问页面
    http.exceptionHandling().accessDeniedPage("/unauth.html");
}
1
2
3
4
5

unauth.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>对不起, 您没有权限访问此页面</h1>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
上次更新: 2024/03/29, 08:56:31
CSRF
初识elasticsearch

← CSRF 初识elasticsearch→

最近更新
01
并行训练
03-29
02
tensor维度转换
03-26
03
ResNet源码解读
03-23
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Geeks_Z | MIT License
京公网安备 11010802040735号 | 京ICP备2022029989号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式