• Spring Security(10)权限处理


    重点记忆:

    1.spring Security的权限配置是在user类的getAuthorities方法中实现的
    2.权限注解@EnableGlobalMethodSecurity(prePostEnabled=true)
    /开启权限注解 //prePostEnabled = true 属性表示开启 Spring Security 中的 @PreAuthorize、@PostAuthorize、@PreFilter 以及 @PostFilter 四个注解

    一.项目配置

    1.1 数据库

    权限表:用户和管理员权限
    在这里插入图片描述

    用户表
    在这里插入图片描述

    角色表:管理员和用户
    在这里插入图片描述

    用户和角色中间表
    在这里插入图片描述

    角色和权限中间表
    在这里插入图片描述

    权限表

    1.2pom.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.1</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.qfedu</groupId>
        <artifactId>security06</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>security06</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>17</java.version>
        </properties>
        <dependencies>
    
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.2</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </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>
        </dependencies>
    
        <build>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml
                    
                
                
                    src/main/resources
                
            
            
                
                    org.springframework.boot
                    spring-boot-maven-plugin
                
            
        
    
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    1.3application.properties

    spring.datasource.username=root
    spring.datasource.password=1234
    spring.datasource.url=jdbc:mysql:///day07db?serverTimezone=Asia/Shanghai
    
    • 1
    • 2
    • 3

    二.SecurityConfig和User配置权限

    2.1 User

    package com.huang.demo.model;
    
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    import java.util.Set;
    
    /**
     * 定义用户对象,需要实现 UserDetails 接口,对于 Spring Security 框架而言,所有的用户对象都是一个 UserDetails 的实例
     *
     * 如实实现接口中的方法就可以了
     */
    public class User implements UserDetails {
        private Integer id;
        private String username;
        private String password;
        private Boolean enabled;
        private Set<String> permissions;
    
        public Set<String> getPermissions() {
            return permissions;
        }
    
        public void setPermissions(Set<String> permissions) {
            this.permissions = permissions;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }
    
        /**
         * 这个方法用来返回当前用户的角色/权限信息
         *
         * 在 Spring Security 中,无论是用户角色,还是用户权限,都是从这个方法返回的
         * @return
         */
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                for (String permission : permissions) {
                    authorities.add(new SimpleGrantedAuthority(permission));
                }
                return authorities;
        }
    
        /**
         * 获取用户密码
         * @return
         */
        @Override
        public String getPassword() {
            return password;
        }
    
        /**
         * 获取用户名
         * @return
         */
        @Override
        public String getUsername() {
            return username;
        }
    
        /**
         * 账户是否没有过期
         *
         * 正常来说,数据库中应该也有一个描述账户是否过期的字段
         * @return
         */
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        /**
         * 账户是否没有被锁定
         * @return
         */
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        /**
         * 密码是否没有过期
         * @return
         */
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        /**
         * 账户是否可用
         * @return
         */
        @Override
        public boolean isEnabled() {
            return enabled;
        }
    }
    
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123

    注意:

    这个方法用来返回当前用户的角色或者权限信息,跟shiro不同的是,spring security分的很明白,能不能访问接口,终究是根据权限来进行判定,而角色只是业务层面的一种分类,而权限是底层获取的判断的值

       /**
         * 这个方法用来返回当前用户的角色/权限信息
         *
         * 在 Spring Security 中,无论是用户角色,还是用户权限,都是从这个方法返回的
         * @return
         */
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                for (String permission : permissions) {
                    authorities.add(new SimpleGrantedAuthority(permission));
                }
                return authorities;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.2 SecurityConfig

    package com.huang.demo.config;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.huang.demo.model.RespBean;
    import com.huang.demo.model.User;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
    import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
    import org.springframework.security.authentication.*;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.security.web.SecurityFilterChain;
    
    import java.io.PrintWriter;
    
    @Configuration
    public class SecurityConfig {
    
        /**
         * admin 继承 user,user 能做的事情,admin 都能做
         * @return
         */
        @Bean
        RoleHierarchy roleHierarchy() {
            RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
            roleHierarchy.setHierarchy("admin > user");
            return roleHierarchy;
        }
    
        /**
         * 自己手动配置安全过滤器链
         *
         * @return
         */
        @Bean
        SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            //开始认证
            http.authorizeRequests()
                    //具备 user 权限则可以访问 /user/** 格式的路径
                                .antMatchers("/user/**").hasAuthority("user")
                                .antMatchers("/admin/**").hasAuthority("admin")
                    //所有的请求,类似于 shiro 中的 /**
                    .anyRequest()
                    //必须要认证之后才能访问,类似于 shiro 中的 authc
                    .authenticated()
                    .and()
                    //开始配置登录表单
                    .formLogin()
                    //配置处理登录请求的接口,本质上其实就是配置过滤器的拦截规则,将来的登录请求就会在过滤器中被处理
                    .loginProcessingUrl("/doLogin")
                    //配置登录表单中用户名的 key
                    .usernameParameter("username")
                    //配置登录表单中用户密码
                    .passwordParameter("password")
                    //登录成功处理器
                    //req:当前请求对象
                    //resp:当前响应对象
                    //auth:当前认证成功的用户信息
                    .successHandler((req, resp, auth) -> {
                        resp.setContentType("application/json;charset=utf-8");
                        User principal = (User) auth.getPrincipal();
                        principal.setPassword(null);
                        RespBean respBean = RespBean.ok("登录成功", principal);
                        String s = new ObjectMapper().writeValueAsString(respBean);
                        resp.getWriter().write(s);
                    })
                    //登录失败的回调
                    .failureHandler((req, resp, e) -> {
                        resp.setContentType("application/json;charset=utf-8");
                        //登录失败可能会有多种原因
                        RespBean respBean = RespBean.error("登录失败");
                        if (e instanceof BadCredentialsException) {
                            respBean.setMsg("用户名或者密码输入错误,登录失败");
                        } else if (e instanceof UsernameNotFoundException) {
                            //默认情况下,这个分支是不会进来的,Spring Security 自动隐藏了了这个异常,如果系统中发生了 UsernameNotFoundException 会被自动转为 BadCredentialsException 异常然后抛出来
                        } else if (e instanceof LockedException) {
                            //如果 com.qfedu.security02.model.User.isAccountNonLocked 方法返回 false,就会进入到这里来
                            respBean.setMsg("账户被锁定,登录失败");
                        } else if (e instanceof AccountExpiredException) {
                            //com.qfedu.security02.model.User.isAccountNonExpired
                            respBean.setMsg("账户过期,登录失败");
                        } else if (e instanceof CredentialsExpiredException) {
                            respBean.setMsg("密码过期,登录失败");
                        } else if (e instanceof DisabledException) {
                            respBean.setMsg("账户被禁用,登录失败");
                        }
                        ObjectMapper om = new ObjectMapper();
                        String s = om.writeValueAsString(respBean);
                        PrintWriter out = resp.getWriter();
                        out.write(s);
                    })
                    .and()
                    //关闭 csrf 防御机制,这个 disable 方法本质上就是从 Spring Security 的过滤器链上移除掉 csrf 过滤器
                    .csrf().disable()
                    .exceptionHandling()
                    //如果用户未登录就访问某一个页面,就会触发当前方法
                    .authenticationEntryPoint((req, resp, authException) -> {
                        resp.setContentType("application/json;charset=utf-8");
                        RespBean respBean = RespBean.error("尚未登录,请登录");
                        String s = new ObjectMapper().writeValueAsString(respBean);
                        resp.getWriter().write(s);
                    });
            return http.build();
        }
    }
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    关键配置

       /**
         * admin 继承 user,user 能做的事情,admin 都能做
         * @return
         */
        @Bean
        RoleHierarchy roleHierarchy() {
            RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
            roleHierarchy.setHierarchy("admin > user");
            return roleHierarchy;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.3.测试

    测试zhangsan用户,是admin,继承了user的所有接口

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    测试 用户lisi ,是user,自然只能访问user的所有接口

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    三. 权限注解—通过权限评估器PermissionEvaluator

    3.1 更改SecurityConfig

    第一步 把SecurityConfig里面的角色继承方法roleHierarchy给注释掉,
    第二步骤权限访问路径注释掉
    第三步加上权限注解@EnableGlobalMethodSecurity(prePostEnabled=true)

    /开启权限注解
    //prePostEnabled = true 属性表示开启 Spring Security 中的 @PreAuthorize、@PostAuthorize、@PreFilter 以及 @PostFilter 四个注解

    即SecurityConfig写成

    package com.huang.demo.config;
    
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.huang.demo.model.RespBean;
    import com.huang.demo.model.User;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
    import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
    import org.springframework.security.authentication.*;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.security.web.SecurityFilterChain;
    
    import java.io.PrintWriter;
    
    @Configuration
    //开启权限注解
    //prePostEnabled = true 属性表示开启 Spring Security 中的 @PreAuthorize、@PostAuthorize、@PreFilter 以及 @PostFilter 四个注解
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig {
    
    /*    *//**
         * admin 继承 user,user 能做的事情,admin 都能做
         * @return
         *//*
        @Bean
        RoleHierarchy roleHierarchy() {
            RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
            roleHierarchy.setHierarchy("admin > user");
            return roleHierarchy;
        }*/
    
        /**
         * 自己手动配置安全过滤器链
         *
         * @return
         */
        @Bean
        SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            //开始认证
            http.authorizeRequests()
                   /* //具备 user 权限则可以访问 /user/** 格式的路径
                                .antMatchers("/user/**").hasAuthority("user")
                                .antMatchers("/admin/**").hasAuthority("admin")*/
                    //所有的请求,类似于 shiro 中的 /**
                    .anyRequest()
                    //必须要认证之后才能访问,类似于 shiro 中的 authc
                    .authenticated()
                    .and()
                    //开始配置登录表单
                    .formLogin()
                    //配置处理登录请求的接口,本质上其实就是配置过滤器的拦截规则,将来的登录请求就会在过滤器中被处理
                    .loginProcessingUrl("/doLogin")
                    //配置登录表单中用户名的 key
                    .usernameParameter("username")
                    //配置登录表单中用户密码
                    .passwordParameter("password")
                    //登录成功处理器
                    //req:当前请求对象
                    //resp:当前响应对象
                    //auth:当前认证成功的用户信息
                    .successHandler((req, resp, auth) -> {
                        resp.setContentType("application/json;charset=utf-8");
                        User principal = (User) auth.getPrincipal();
                        principal.setPassword(null);
                        RespBean respBean = RespBean.ok("登录成功", principal);
                        String s = new ObjectMapper().writeValueAsString(respBean);
                        resp.getWriter().write(s);
                    })
                    //登录失败的回调
                    .failureHandler((req, resp, e) -> {
                        resp.setContentType("application/json;charset=utf-8");
                        //登录失败可能会有多种原因
                        RespBean respBean = RespBean.error("登录失败");
                        if (e instanceof BadCredentialsException) {
                            respBean.setMsg("用户名或者密码输入错误,登录失败");
                        } else if (e instanceof UsernameNotFoundException) {
                            //默认情况下,这个分支是不会进来的,Spring Security 自动隐藏了了这个异常,如果系统中发生了 UsernameNotFoundException 会被自动转为 BadCredentialsException 异常然后抛出来
                        } else if (e instanceof LockedException) {
                            //如果 com.qfedu.security02.model.User.isAccountNonLocked 方法返回 false,就会进入到这里来
                            respBean.setMsg("账户被锁定,登录失败");
                        } else if (e instanceof AccountExpiredException) {
                            //com.qfedu.security02.model.User.isAccountNonExpired
                            respBean.setMsg("账户过期,登录失败");
                        } else if (e instanceof CredentialsExpiredException) {
                            respBean.setMsg("密码过期,登录失败");
                        } else if (e instanceof DisabledException) {
                            respBean.setMsg("账户被禁用,登录失败");
                        }
                        ObjectMapper om = new ObjectMapper();
                        String s = om.writeValueAsString(respBean);
                        PrintWriter out = resp.getWriter();
                        out.write(s);
                    })
                    .and()
                    //关闭 csrf 防御机制,这个 disable 方法本质上就是从 Spring Security 的过滤器链上移除掉 csrf 过滤器
                    .csrf().disable()
                    .exceptionHandling()
                    //如果用户未登录就访问某一个页面,就会触发当前方法
                    .authenticationEntryPoint((req, resp, authException) -> {
                        resp.setContentType("application/json;charset=utf-8");
                        RespBean respBean = RespBean.error("尚未登录,请登录");
                        String s = new ObjectMapper().writeValueAsString(respBean);
                        resp.getWriter().write(s);
                    });
            return http.build();
        }
    }
    
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    3.2配置权限评估器MyPermissionEvaluator

    配置这个工具类是为了把User里面获取用户权限的方法getAuthorities抽离出来。

    package com.huang.demo.config;
    import org.springframework.security.access.PermissionEvaluator;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.stereotype.Component;
    import org.springframework.util.AntPathMatcher;
    import java.io.Serializable;
    import java.util.Collection;
    
    
    //处理了获取权限的问题
    @Component
    public class MyPermissionEvaluator implements PermissionEvaluator {
        private AntPathMatcher pathMatcher = new AntPathMatcher();
        @Override
        public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
            //获取当前用户具备的权限
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                if (pathMatcher.match(authority.getAuthority(), (String) permission)) {
                    //说明当前登录的用户具备访问该接口所需要的权限
                    return true;
                }
            }
            return false;
        }
    
    
    
    
        @Override
        public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
            return false;
        }
    }
    
    • 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

    注意:

    hasPermission为重点方法,传入三个参数
    1.authentication,当前用户角色
    2.不重要
    3.permission当前用户所需要的权限

    3.3 改权限表permission

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    方便我们接下来细分权限。

    3.4 写接口UserController

    UserController

    package com.huang.demo.controller;
    
    import org.springframework.security.access.prepost.PreAuthorize;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    
        /**
         * 当前用户具备 user 角色的时候,就可以访问 user 接口
         * @return
         */
        @GetMapping("/user/hello")
        //判断用户具备 user 权限才能访问
    //    @PreAuthorize("hasAuthority('user')")
    //    @PreAuthorize("hasPermission(#principal,'user:select')")
        @PreAuthorize("hasPermission(#principal,'user:select')")
        public String hello() {
            return "hello user";
        }
    
    
    
    
    
        /**
         * 当前用户具备 user 角色的时候,就可以访问 user 接口
         * @return
         */
    
        @DeleteMapping("/user/delete")
        //判断用户具备 user 权限才能访问
    //    @PreAuthorize("hasAuthority('user')")
    //    @PreAuthorize("hasPermission(#principal,'user:select')")
        @PreAuthorize("hasPermission(#principal,'user:delete')")
        public String delete() {
            return "删除成功";
        }
    
    
    
    
    
        /**
         * 当前用户具备 admin 角色的时候,就可以访问 admin 接口
         * @return
         */
        @GetMapping("/admin/hello")
        @PreAuthorize("hasPermission(#principal,'admin')")
        public String admin() {
            return "hello admin";
        }
    }
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    3.5 关于 @PreAuthorize注解的第二种写法

     @PreAuthorize("hasPermission(#principal,'user:select')")
    
    • 1

    一样可以实现,过几天加测

    3.6测试

    3.6.1 使用测试用户-lisi-user-user:select

    在这里插入图片描述
    在这里插入图片描述

    用户查询成功
    
    • 1

    在这里插入图片描述

    用户查询失败,报错403说明没有该权限,即我们的权限注解起到了作用。让user用户lisi只能做他有的权限
    在这里插入图片描述

    同理,user用户lisi没办法登录管理员的接口

    在这里插入图片描述

    3.6.2 使用测试用户-admin-zhangsan-admin去测试

    在这里插入图片描述

    zhangsan用户具有管理员的所有权限
    在这里插入图片描述

    可以进行管理员查询
    在这里插入图片描述

    但是依旧没有办法做用户查询
    在这里插入图片描述

    四.

  • 相关阅读:
    Ubuntu20 安装 JupyterLab
    Vue (十一) --------- 过渡与动画
    抖音短视频实操:矩阵号之为什么要做矩阵号和如何做矩阵号(下)
    计算机毕业设计(附源码)python智慧后勤app
    SquirrelMail实现Web方式收发邮件_xionglling的博客-CSDN博客
    Android 13.0 USB鼠标右键改成返回键的功能实现
    JK405R-SOP16录音芯片ic方案的测试板使用说明以及咪头如何选择
    2.力扣c++刷题-->移除元素
    「Verilog学习笔记」使用函数实现数据大小端转换
    Linux中的进程等待(超详细)
  • 原文地址:https://blog.csdn.net/weixin_43189971/article/details/125886458