旅游网后台管理系统(三)权限操作

文章目录

1. 创建表

1.1 表之间的关系

在这里插入图片描述

  • 用户表与角色表之间的关系:多对多
  • 角色表与权限表之间的关系:多对多

1.2 用户表

序号 字段名称 字段类型 字段描述
1 id int(11) 主键,自增长
2 email varchar(50) 邮箱,非空,唯一
3 userName varchar(50) 用户名
4 password varchar(100) 密码
5 phoneNum varchar(50) 电话
6 status int(11) 状态(0未开启 1开启)
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(50) NOT NULL,
  `userName` varchar(50) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `phoneNum` varchar(50) DEFAULT NULL,
  `status` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `users` VALUES ('1', '[email protected]', '张三', '$2a$10$7u0aq7hSJ8xFNEFXESRgfObOZw7YxV.YVHNOiMentENOIForpkQzS', '13333333333', '1');
INSERT INTO `users` VALUES ('2', '[email protected]', '李四', '$2a$10$7u0aq7hSJ8xFNEFXESRgfObOZw7YxV.YVHNOiMentENOIForpkQzS', '12222222222', '1');

1.3 角色表

序号 字段名称 字段类型 字段描述
1 id int(11) 主键,自增长
2 roleName varchar(50) 用户名
3 roleDesc varchar(50) 用户描述
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `roleName` varchar(50) DEFAULT NULL,
  `roleDesc` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `role` VALUES ('1', 'USER', '用户');
INSERT INTO `role` VALUES ('2', 'ADMIN', '管理员');

1.4 用户与角色的中间表

序号 字段名称 字段类型 字段描述
1 usersId int(11) 用户 id(外键)
2 roleId int(11) 角色 id(外键)
DROP TABLE IF EXISTS `users_role`;
CREATE TABLE `users_role` (
  `usersId` int(11) NOT NULL,
  `roleId` int(11) NOT NULL,
  PRIMARY KEY (`usersId`,`roleId`),
  KEY `roleId` (`roleId`),
  CONSTRAINT `users_role_ibfk_1` FOREIGN KEY (`usersId`) REFERENCES `users` (`id`),
  CONSTRAINT `users_role_ibfk_2` FOREIGN KEY (`roleId`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `users_role` VALUES ('1', '1');
INSERT INTO `users_role` VALUES ('2', '2');

1.5 权限表

序号 字段名称 字段类型 字段描述
1 id int(11) 主键,自增长
2 permissionName varchar(50) 权限名
3 url varchar(50) 资源路径
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `permissionName` varchar(50) DEFAULT NULL,
  `url` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

INSERT INTO `permission` VALUES ('1', 'user', '/user/*.do');
INSERT INTO `permission` VALUES ('2', 'product', '/product/*.do');
INSERT INTO `permission` VALUES ('3', 'orders', '/orders/*.do');
INSERT INTO `permission` VALUES ('4', 'role', '/role/*.do');
INSERT INTO `permission` VALUES ('5', 'permission', '/permission/*.do');
INSERT INTO `permission` VALUES ('6', 'sysLog', '/sysLog/*.do');

1.6 角色与权限的中间表

序号 字段名称 字段类型 字段描述
1 permissionId int(11) 权限 id(外键)
2 roleId int(11) 角色 id(外键)
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
  `permissionId` int(11) NOT NULL,
  `roleId` int(11) NOT NULL,
  PRIMARY KEY (`permissionId`,`roleId`),
  KEY `roleId` (`roleId`),
  CONSTRAINT `role_permission_ibfk_1` FOREIGN KEY (`permissionId`) REFERENCES `permission` (`id`),
  CONSTRAINT `role_permission_ibfk_2` FOREIGN KEY (`roleId`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `role_permission` VALUES ('2', '1');
INSERT INTO `role_permission` VALUES ('3', '1');
INSERT INTO `role_permission` VALUES ('1', '2');
INSERT INTO `role_permission` VALUES ('2', '2');
INSERT INTO `role_permission` VALUES ('3', '2');
INSERT INTO `role_permission` VALUES ('4', '2');
INSERT INTO `role_permission` VALUES ('5', '2');
INSERT INTO `role_permission` VALUES ('6', '2');

2. Spring Security

2.1 Spring Security 介绍

Spring Security 是 Spring 项目组中用来提供安全认证服务的框架

安全包括两个主要操作:

  1. 认证:验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。比如登陆时,校验用户名密码是否正确来完成认证过程。
  2. 授权:用户授权指的是验证某个用户是否有权限执行某个操作

2.2 Spring Security 快速入门

  1. 创建一个 maven 项目,骨架选择 web-app

  2. 导入依赖坐标

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    
  3. 配置 web.xml

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-security.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  4. 配置 spring-security.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:security="http://www.springframework.org/schema/security"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security.xsd">
    
        <security:http auto-config="true" use-expressions="false">
            <!-- intercept-url定义一个过滤规则 pattern表示对哪些 url 进行权限控制,access 属性表示在请求对应的 URL 时需要什么权限 -->
            <security:intercept-url pattern="/**" access="ROLE_USER"/>
        </security:http>
        <security:authentication-manager>
            <security:authentication-provider>
                <security:user-service>
                    <!--配置用户信息-->
                    <security:user name="user" password="{noop}user" authorities="ROLE_USER"/>
                    <security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
                </security:user-service>
            </security:authentication-provider>
        </security:authentication-manager>
    </beans>
    
  5. 测试

    1. 启动项目

      tomcat7:run
      
    2. 打开浏览器,输入

      http://localhost:8090
      
    3. 自动进入登陆页面(因为我们配置了 auto-config=”true”,Spring Security 自动为我们生成了登陆页面)

      http://localhost:8090/login
      
    4. 输入以下内容,进入 index.jsp

      User:user
      Password:user
      
    5. 输入以下内容,报 403 错误(权限不够访问)

      User:admin
      Password:admin
      
    6. 输入其他内容,页面给出提示

      User:123
      Password:123
      

2.3 使用自定义页面

  1. 修改 spring-security.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:security="http://www.springframework.org/schema/security"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security.xsd">
    
        <!-- 配置不过滤的资源(静态资源及登录相关) -->
        <security:http security="none" pattern="/login.html"/>
        <security:http security="none" pattern="/success.html"/>
        <security:http security="none" pattern="/failer.html"/>
        <security:http auto-config="true" use-expressions="false">
            <!-- intercept-url定义一个过滤规则 pattern表示对哪些 url 进行权限控制,access 属性表示在请求对应的 URL 时需要什么权限 -->
            <security:intercept-url pattern="/**" access="ROLE_USER"/>
            <!-- 自定义登陆页面
                 login-page 自定义登陆页面,
                 authentication-failure-url 用户权限校验失败之后才会跳转到这个页面,
                 default-target-url 登陆成功后跳转的页面。 -->
            <security:form-login login-page="/login.html"
                                 login-processing-url="/login"
                                 username-parameter="username" 
                                 password-parameter="password"
                                 authentication-failure-url="/failer.html"
                                 default-target-url="/success.html"/>
            <!-- 关闭 CSRF ,默认是开启的 -->
            <security:csrf disabled="true"/>
        </security:http>
        <security:authentication-manager>
            <security:authentication-provider>
                <security:user-service>
                    <!--配置用户信息-->
                    <security:user name="user" password="{noop}user" authorities="ROLE_USER"/>
                    <security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
                </security:user-service>
            </security:authentication-provider>
        </security:authentication-manager>
    </beans>
    
  2. 编写 login.html

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Insert title here</title></head>
    <body>
    <form action="login" method="post">
        <table>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="username"/></td>
            </tr>
            <tr>
                <td>密码:</td>
                <td><input type="password" name="password"/></td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" value="登录"/>
                    <input type="reset" value="重置"/>
                </td>
            </tr>
        </table>
    </form>
    </body>
    </html>
    
  3. 编写 success.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h2>success</h2>
    </body>
    </html>
    
  4. 编写 failer.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h2>failer</h2>
    </body>
    </html>
    
  5. 测试

    1. 启动项目

      tomcat7:run
      
    2. 打开浏览器,输入

      http://localhost:8090
      
    3. 自动进入 login.html

      http://localhost:8090/login.html
      
    4. 输入以下内容,进入 success.html

      User:user
      Password:user
      
    5. 输入以下内容,进入 success.html

      User:admin
      Password:admin
      
    6. 输入其他内容,进入 failer.html

      User:123
      Password:123
      

2.4 Spring Security 使用数据库认证

在 Spring Security 中如果想要使用数据进行认证操作,有很多种操作方式,这里我们介绍使用 UserDetails,UserDetailsService 来完成操作。

  • UserDetails

    UserDetails 是一个接口,作用是封装当前进行认证的用户信息,但由于其是一个接口,所以我们可以对其进行实现

  • UserDetailsService

    UserDetailsService 是一个接口,作用是规范用于认证的方法,但由于其是一个接口,所以我们可以对其进行实现

3. 用户操作

3.1 用户登录与退出

3.1.1 用户登录流程分析

在这里插入图片描述

3.1.2 实现用户登录操作

  1. 导入 Spring Security 依赖

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    
  2. 配置 web.xml

    <!-- 配置 Spring 的监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 设置配置文件的路径 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring-security.xml</param-value>
    </context-param>
    
    <!-- 配置 spring-security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  3. 配置 spring-security.xml(相当于代替了控制层的代码)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:security="http://www.springframework.org/schema/security"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd">
    
        <!-- 配置不拦截的资源 -->
        <security:http pattern="/login.jsp" security="none"/>
        <security:http pattern="/failer.jsp" security="none"/>
        <security:http pattern="/css/**" security="none"/>
        <security:http pattern="/img/**" security="none"/>
        <security:http pattern="/plugins/**" security="none"/>
    
        <!-- 配置具体的规则
        	auto-config="true"	不用自己编写登录的页面,框架提供默认登录页面
        	use-expressions="false"	是否使用 SPEL 表达式(没学习过)
    	-->
        <security:http auto-config="true" use-expressions="false">
            <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有 ROLE_USER 或者 ROLE_ADMIN 的角色" -->
            <security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>
    
            <!-- 定义跳转的具体的页面 -->
            <security:form-login
                    login-page="/login.jsp"
                    login-processing-url="/login.do"
                    default-target-url="/index.jsp"
                    authentication-failure-url="/failer.jsp"
                    authentication-success-forward-url="/pages/main.jsp"/>
    
            <!-- 关闭跨域请求 -->
            <security:csrf disabled="true"/>
    
            <!-- 退出 -->
            <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />
        </security:http>
    
        <!-- 切换成数据库中的用户名和密码 -->
        <security:authentication-manager>
            <security:authentication-provider user-service-ref="userService">        			</security:authentication-provider>
        </security:authentication-manager>
    
    </beans>
    
    
  4. 编写实现类

    /**
     * 用户实体类
     */
    public class UserInfo implements Serializable {
        private Integer id; // 主键
        private String email; // 邮箱
        private String username; // 用户名
        private String password; // 密码
        private String phoneNum; // 电话
        private Integer status; // 状态(0未开启 1开启)
        private String statusStr; // 状态字符串
        private List<Role> roles; // 角色
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getPhoneNum() {
            return phoneNum;
        }
    
        public void setPhoneNum(String phoneNum) {
            this.phoneNum = phoneNum;
        }
    
        public Integer getStatus() {
            return status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        public String getStatusStr() {
            if(status != null){
                if(status == 0){
                    statusStr = "未开启";
                }
                if(status == 1){
                    statusStr = "开启";
                }
            }
            return statusStr;
        }
    
        public void setStatusStr(String statusStr) {
            this.statusStr = statusStr;
        }
    
        public List<Role> getRoles() {
            return roles;
        }
    
        public void setRoles(List<Role> roles) {
            this.roles = roles;
        }
    
        @Override
        public String toString() {
            return "UserInfo{" +
                    "id=" + id +
                    ", email='" + email + '\'' +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", phoneNum='" + phoneNum + '\'' +
                    ", status=" + status +
                    ", statusStr='" + statusStr + '\'' +
                    ", roles=" + roles +
                    '}';
        }
    }
    
    
    /**
     * 角色实体类
     */
    public class Role implements Serializable {
        private Integer id; // 主键
        private String roleName; //角色名
        private String roleDesc; // 角色描述
        private List<Permission> permissions; // 权限
        private List<UserInfo> users; // 角色
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getRoleName() {
            return roleName;
        }
    
        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }
    
        public String getRoleDesc() {
            return roleDesc;
        }
    
        public void setRoleDesc(String roleDesc) {
            this.roleDesc = roleDesc;
        }
    
        public List<Permission> getPermissions() {
            return permissions;
        }
    
        public void setPermissions(List<Permission> permissions) {
            this.permissions = permissions;
        }
    
        public List<UserInfo> getUsers() {
            return users;
        }
    
        public void setUsers(List<UserInfo> users) {
            this.users = users;
        }
    
        @Override
        public String toString() {
            return "Role{" +
                    "id=" + id +
                    ", roleName='" + roleName + '\'' +
                    ", roleDesc='" + roleDesc + '\'' +
                    ", permissions=" + permissions +
                    ", users=" + users +
                    '}';
        }
    }
    
    
    /**
     * 权限实体类
     */
    public class Permission implements Serializable {
        private Integer id; // 主键
        private String permissionName; // 权限名
        private String url; // 资源路径
        private List<Role> roles; // 角色
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getPermissionName() {
            return permissionName;
        }
    
        public void setPermissionName(String permissionName) {
            this.permissionName = permissionName;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public List<Role> getRoles() {
            return roles;
        }
    
        public void setRoles(List<Role> roles) {
            this.roles = roles;
        }
    
        @Override
        public String toString() {
            return "Permission{" +
                    "id=" + id +
                    ", permissionName='" + permissionName + '\'' +
                    ", url='" + url + '\'' +
                    ", roles=" + roles +
                    '}';
        }
    }
    
    
  5. 编写持久层接口

    @Repository
    public interface UserDao {
        /**
         * 根据用户名查询用户信息
         * @param userName
         * @return
         * @throws Exception
         */
        @Select("select * from users where userName = #{userName}")
        @Results({
                @Result(id = true, property = "id", column = "id"),
                @Result(property = "email", column = "email"),
                @Result(property = "username", column = "username"),
                @Result(property = "password", column = "password"),
                @Result(property = "phoneNum", column = "phoneNum"),
                @Result(property = "status", column = "status"),
                @Result(property = "roles", column = "id", many = @Many(select = "com.zt.dao.RoleDao.findById"))
        })
        UserInfo findByUsername(String userName) throws Exception;
    }
    
    public interface RoleDao {
        /**
         * 根据用户 ID 查询用户角色
         *
         * @param id
         * @return
         */
        @Select("select * from role where id in (select roleId from users_role where usersId = #{id})")
        List<Role> findById(Integer id) throws Exception;
    }
    
  6. 编写业务层接口和实现类

    public interface UserService extends UserDetailsService {
    }
    
    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            UserInfo userInfo = null;
            try {
                userInfo = userDao.findByUsername(username);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 将自己的用户对象封装为一个 UserDetails
            User user = new User(userInfo.getUsername(),
                    "{noop}" + userInfo.getPassword(),
                    userInfo.getStatus() == 1, true, true, true,
                    getAuthorities(userInfo.getRoles()));
            
            return user;
        }
    
        // 返回一个 List 集合,集合中装的是角色信息
        public List<SimpleGrantedAuthority> getAuthorities(List<Role> roles){
            ArrayList<SimpleGrantedAuthority> authorities = new ArrayList<>();
            for (Role role : roles) {
                authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
            }
            return authorities;
        }
    
    
    }
    
    
  7. 在 webapp 下添加 login.jsp,failer.jsp

3.1.3 实现用户退出操作

  1. 配置 spring-security.xml

    <!-- 退出 -->
    <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />
    
  2. 给注销按钮链接赋值

    ${pageContext.request.contextPath}/logout.do
    

3.2 查询所有用户

3.2.1 查询所有用户流程分析

在这里插入图片描述

3.2.2 实现查询所有用户操作

  1. 编写持久层接口

    package com.zt.dao;
    
    import com.zt.domain.UserInfo;
    import org.apache.ibatis.annotations.Many;
    import org.apache.ibatis.annotations.Result;
    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.Select;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface UserDao {
        
        /**
         * 查询所有用户信息
         * @return
         * @throws Exception
         */
        @Select("select * from users")
        List<UserInfo> findAll() throws Exception;
    }
    
  2. 编写业务层接口和实现类

    public interface UserService extends UserDetailsService {
        /**
         * 查询所有用户
         * @return
         * @throws Exception
         */
        List<UserInfo> findAll() throws Exception;
    }
    
    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        /**
         * 查询所有用户
         * @return
         * @throws Exception
         */
        @Override
        public List<UserInfo> findAll() throws Exception {
            return userDao.findAll();
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        private UserService userService;
    
        /**
         * 查询所有用户
         * @return
         * @throws Exception
         */
        @RequestMapping("/findAll")
        public ModelAndView findAll() throws Exception{
            ModelAndView modelAndView = new ModelAndView();
            List<UserInfo> users = userService.findAll();
            modelAndView.addObject("userList",users);
            modelAndView.setViewName("user-list");
    
            return modelAndView;
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 user-list.jsp

3.3 添加用户

3.3.1 添加用户流程分析

在这里插入图片描述

3.3.2 实现添加用户操作

  1. 配置 spring-security.xml

    <!-- 配置加密类 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    
  2. 编写持久层接口

    package com.zt.dao;
    
    import com.zt.domain.UserInfo;
    import org.apache.ibatis.annotations.*;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface UserDao {
    
        /**
         * 添加用户
         * @param userInfo
         * @throws Exception
         */
        @Insert("insert into users(email,userName,password,phoneNum,status) values(#{email},#{username},#{password},#{phoneNum},#{status})")
        void save(UserInfo userInfo) throws Exception;
    }
    
  3. 编写业务层接口和实现类

    public interface UserService extends UserDetailsService {
        /**
         * 添加用户
         * @param userInfo
         * @throws Exception
         */
        void save(UserInfo userInfo) throws Exception;
    }
    
    
    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        /**
         * 添加用户
         *
         * @param userInfo
         * @throws Exception
         */
        @Override
        public void save(UserInfo userInfo) throws Exception {
            // 对密码进行加密
            userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword()));
            userDao.save(userInfo);
        }
    }
    
    
  4. 编写控制层

    @Controller
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        private UserService userService;
    
        /**
         * 添加用户
         * @param userInfo
         * @return
         * @throws Exception
         */
        @RequestMapping("/save.do")
        public String save(UserInfo userInfo) throws Exception{
            userService.save(userInfo);
            return "redirect:findAll.do";
        }
    }
    
    
  5. 编写 JSP 页面

    在 pages 包中创建 user-add.jsp

3.3.3 解决密码加密后用户登录问题

  1. 提出问题

    添加用户后,由于密码进行了加密,当我们用添加的用户进行登录时,登陆失败了

  2. 分析问题

    这是因为我们数据库中存储的密码是加密后的,我们读取时并没有对其解密,所以与输入密码不一致

  3. 解决问题

    1. 配置 spring-security.xml

      <!-- 切换成数据库中的用户名和密码 -->
      <security:authentication-manager>
          <security:authentication-provider user-service-ref="userService">
              <!-- 配置加密的方式 -->
              <security:password-encoder ref="passwordEncoder"/>
          </security:authentication-provider>
      </security:authentication-manager>
      
      
    2. 删除 UserServiceImpl 中的 “{noop}”

      @Service("userService")
      public class UserServiceImpl implements UserService {
          @Autowired
          private UserDao userDao;
      
          @Override
          public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
              UserInfo userInfo = null;
              try {
                  userInfo = userDao.findByUsername(username);
              } catch (Exception e) {
                  e.printStackTrace();
              }
              // 将自己的用户对象封装为一个 UserDetails
              User user = new User(userInfo.getUsername(),
                      userInfo.getPassword(),
                      userInfo.getStatus() == 1, true, true, true,
                      getAuthorities(userInfo.getRoles()));
      
              return user;
          }
      
          // 返回一个 List 集合,集合中装的是角色信息
          public List<SimpleGrantedAuthority> getAuthorities(List<Role> roles) {
              ArrayList<SimpleGrantedAuthority> authorities = new ArrayList<>();
              for (Role role : roles) {
                  authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
              }
              return authorities;
          }
      
      }
      
      

3.4 查询用户详情

3.4.1 查询用户详情流程分析

在这里插入图片描述

3.4.2 实现查询用户详情操作

  1. 编写持久层接口

    @Repository
    public interface UserDao {
        
        /**
         * 查询单个用户详细信息
         *
         * @param id
         * @return
         * @throws Exception
         */
        @Select("select * from users where id=#{id}")
        @Results({
                @Result(id = true, property = "id", column = "id"),
                @Result(property = "email", column = "email"),
                @Result(property = "username", column = "username"),
                @Result(property = "password", column = "password"),
                @Result(property = "phoneNum", column = "phoneNum"),
                @Result(property = "status", column = "status"),
                @Result(property = "roles", column = "id", many = @Many(select = "com.zt.dao.RoleDao.findById"))
        })
        UserInfo findById(Integer id) throws Exception;
    }
    
    @Repository
    public interface RoleDao {
        /**
         * 根据用户 ID 查询角色
         *
         * @param id
         * @return
         */
        @Select("select * from role where id in (select roleId from users_role where usersId = #{id})")
        @Results({
                @Result(id = true, property = "id", column = "id"),
                @Result(property = "roleName", column = "roleName"),
                @Result(property = "roleDesc", column = "roleDesc"),
                @Result(property = "permissions", column ="id",many = @Many(select = "com.zt.dao.PermissionDao.findById"))
        })
        List<Role> findById(Integer id) throws Exception;
    }
    
    
    @Repository
    public interface PermissionDao {
        /**
         * 根据角色 ID 查询权限
         * @param id
         * @return
         * @throws Exception
         */
        @Select("select * from permission where id in (select permissionId from role_permission where roleId = #{id})")
        List<Permission> findById(Integer id) throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface UserService extends UserDetailsService {
    
        /**
         * 查询单个用户详细信息
         * @param id
         * @return
         * @throws Exception
         */
        UserInfo findById(Integer id) throws Exception;
    }
    
    
    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        /**
         * 查询单个用户详细信息
         * @param id
         * @return
         * @throws Exception
         */
        @Override
        public UserInfo findById(Integer id) throws Exception {
            return userDao.findById(id);
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        private UserService userService;
    
        /**
         * 查询单个用户详细信息
         * @param id
         * @return
         * @throws Exception
         */
        @RequestMapping("/findById.do")
        public ModelAndView findById(Integer id) throws Exception{
            ModelAndView modelAndView = new ModelAndView();
            UserInfo user = userService.findById(id);
            modelAndView.addObject("user",user);
            modelAndView.setViewName("user-show");
            return modelAndView;
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 user-show.jsp

4. 角色操作

4.1 查询所有角色

4.1.1 查询所有角色流程分析

在这里插入图片描述

4.1.2 实现查询所有角色操作

  1. 编写持久层接口

    @Repository
    public interface RoleDao {
    
        /**
         * 查询所有角色
         * @return
         * @throws Exception
         */
        @Select("select * from role")
        List<Role> findAll() throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface RoleService {
        /**
         * 查询所有角色
         * @return
         * @throws Exception
         */
        List<Role> findAll() throws Exception;
    }
    
    
    @Transactional
    @Service("roleService")
    public class RoleServiceImpl implements RoleService {
        @Autowired
        private RoleDao roleDao;
        
        /**
         * 查询所有角色
         * @return
         * @throws Exception
         */
        @Override
        public List<Role> findAll() throws Exception {
            return roleDao.findAll();
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/role")
    public class RoleController {
        @Autowired
        private RoleService roleService;
    
        /**
         * 查询所有角色
         * @return
         * @throws Exception
         */
        @RequestMapping("/findAll.do")
        public ModelAndView findAll() throws Exception {
            ModelAndView modelAndView = new ModelAndView();
            List<Role> roleList = roleService.findAll();
            modelAndView.addObject("roleList",roleList);
            modelAndView.setViewName("role-list");
            return modelAndView;
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 role-list.jsp

4.2 添加角色

4.2.1 添加角色流程分析

在这里插入图片描述

4.2.2 实现添加角色操作

  1. 编写持久层接口

    @Repository
    public interface RoleDao {
    
        /**
         * 添加角色
         * @param role
         * @throws Exception
         */
        @Insert("insert into role(roleName,roleDesc) values(#{roleName},#{roleDesc})")
        void save(Role role) throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface RoleService {
    
        /**
         * 添加角色
         * @param role
         * @throws Exception
         */
        void save(Role role) throws Exception;
    }
    
    
    @Transactional
    @Service("roleService")
    public class RoleServiceImpl implements RoleService {
        @Autowired
        private RoleDao roleDao;
    
        /**
         * 添加角色
         * @param role
         * @throws Exception
         */
        @Override
        public void save(Role role) throws Exception {
            roleDao.save(role);
        }
    }
    
  3. 编写控制层

    @Controller
    @RequestMapping("/role")
    public class RoleController {
        @Autowired
        private RoleService roleService;
    
        /**
         * 添加角色
         * @param role
         * @return
         * @throws Exception
         */
        @RequestMapping("/save.do")
        public String save(Role role) throws Exception {
            roleService.save(role);
            return "redirect:findAll.do";
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 user-add.jsp

4.3 查询角色详情

4.3.1 实现查询角色详情操作

  1. 编写持久层接口

    @Repository
    public interface RoleDao {
    
        /**
         * 查询角色详情
         *
         * @param id
         * @return
         */
        @Select("select * from role where id=#{id}")
        @Results({
                @Result(id = true, property = "id", column = "id"),
                @Result(property = "roleName",column = "roleName"),
                @Result(property = "roleDesc",column = "roleDesc"),
                @Result(property = "permissions", column = "id", many = @Many(select = "com.zt.dao.PermissionDao.findById"))
        })
        Role findByRoleId(Integer id) throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface RoleService {
    
        /**
         * 查询角色详情
         * @param id
         * @return
         * @throws Exception
         */
        Role findById(Integer id) throws Exception;
    }
    
    
    @Transactional
    @Service("roleService")
    public class RoleServiceImpl implements RoleService {
        @Autowired
        private RoleDao roleDao;
    
        /**
         * 查询角色详情
         * @param id
         * @return
         * @throws Exception
         */
        @Override
        public Role findById(Integer id) throws Exception {
            return roleDao.findByRoleId(id);
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/role")
    public class RoleController {
        @Autowired
        private RoleService roleService;
    
        /**
         * 查询角色详情
         * @param id
         * @return
         * @throws Exception
         */
        @RequestMapping("/findById.do")
        public ModelAndView findById(Integer id) throws Exception {
            ModelAndView modelAndView = new ModelAndView();
            Role role = roleService.findById(id);
            modelAndView.addObject("role",role);
            modelAndView.setViewName("role-show");
            return modelAndView;
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 role-show.jsp

4.4 删除角色

4.4.1 实现删除角色操作

  1. 编写持久层接口

    @Repository
    public interface RoleDao {
    
        /**
         * 删除角色所拥有的所有权限
         * @param id
         * @throws Exception
         */
        @Delete("delete from role_permission where roleId = #{id}")
        void deleteFromRole_PermissionByRoleId(Integer id) throws Exception;
    
        /**
         * 删除用户所拥有的这种角色
         * @param id
         * @throws Exception
         */
        @Delete("delete from users_role where roleId = #{id}")
        void deleteFromUsers_RoleByRoleId(Integer id) throws Exception;
    
        /**
         * 删除角色
         * @param id
         * @throws Exception
         */
        @Delete("delete from role where id = #{id}")
        void deleteRole(Integer id) throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface RoleService {
    
        /**
         * 删除角色
         * @param id
         * @throws Exception
         */
        void deleteRole(Integer id) throws Exception;
    }
    
    
    @Transactional
    @Service("roleService")
    public class RoleServiceImpl implements RoleService {
        @Autowired
        private RoleDao roleDao;
    
        /**
         * 删除角色
         * @param id
         * @throws Exception
         */
        @Override
        public void deleteRole(Integer id) throws Exception {
            roleDao.deleteFromRole_PermissionByRoleId(id);
            roleDao.deleteFromUsers_RoleByRoleId(id);
            roleDao.deleteRole(id);
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/role")
    public class RoleController {
        @Autowired
        private RoleService roleService;
    
        /**
         * 删除角色
         * @param id
         * @return
         * @throws Exception
         */
        @RequestMapping("/deleteRole.do")
        public String deleteRole(Integer id) throws Exception {
            roleService.deleteRole(id);
            return "redirect:findAll.do";
        }
    }
    
    

5. 权限操作

5.1 查询所有权限

5.1.1 实现查询所有权限操作

  1. 编写持久层接口

    @Repository
    public interface PermissionDao {
        /**
         * 查询所有权限
         * @return
         * @throws Exception
         */
        @Select("select * from permission")
        List<Permission> findAll() throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface PermissionService {
    
        /**
         * 查询所有权限
         * @return
         * @throws Exception
         */
        List<Permission> findAll() throws Exception;
    }
    
    
    @Transactional
    @Service("permissionService")
    public class PermissionServiceImpl implements PermissionService {
        @Autowired
        private PermissionDao permissionDao;
    
        /**
         * 查询所有权限
         * @return
         * @throws Exception
         */
        @Override
        public List<Permission> findAll() throws Exception {
            return permissionDao.findAll();
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/permission")
    public class PermissionController {
        @Autowired
        private PermissionService permissionService;
    
        /**
         * 查询所有权限
         * @return
         * @throws Exception
         */
        @RequestMapping("/findAll.do")
        public ModelAndView findAll() throws Exception {
            ModelAndView modelAndView = new ModelAndView();
            List<Permission> permissionList = permissionService.findAll();
            modelAndView.addObject("permissionList",permissionList);
            modelAndView.setViewName("permission-list");
            return modelAndView;
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 permission-list.jsp

5.2 添加权限

5.2.1 实现添加权限操作

  1. 编写持久层接口

    @Repository
    public interface PermissionDao {
        /**
         * 添加权限
         * @param permission
         * @throws Exception
         */
        @Insert("insert into permission(permissionName,url) values(#{permissionName},#{url})")
        void save(Permission permission) throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface PermissionService {
        /**
         * 添加权限
         * @throws Exception
         */
        void save(Permission permission) throws Exception;
    }
    
    
    @Transactional
    @Service("permissionService")
    public class PermissionServiceImpl implements PermissionService {
        @Autowired
        private PermissionDao permissionDao;
    
        /**
         * 添加权限
         * @param permission
         * @throws Exception
         */
        @Override
        public void save(Permission permission) throws Exception {
            permissionDao.save(permission);
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/permission")
    public class PermissionController {
        @Autowired
        private PermissionService permissionService;
    
        /**
         * 添加权限
         * @param permission
         * @return
         * @throws Exception
         */
        @RequestMapping("/save.do")
        public String save(Permission permission) throws Exception {
            permissionService.save(permission);
            return "redirect:findAll.do";
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 permission-add.jsp

5.3 删除权限

5.3.1 实现删除权限操作

  1. 编写持久层接口

    @Repository
    public interface PermissionDao {
    
        /**
         * 删除角色所拥有的该权限
         * @param id
         */
        @Delete("delete from role_permission where permissionId = #{id}")
        void deleteFromRole_PermissionByPermissionId(Integer id) throws Exception;
    
        /**
         * 删除权限
         * @param id
         */
        @Delete("delete from permission where id = #{id}")
        void deletePermission(Integer id) throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface PermissionService {
    
        /**
         * 删除权限
         * @param id
         * @throws Exception
         */
        void deletePermission(Integer id) throws Exception;
    }
    
    
    @Transactional
    @Service("permissionService")
    public class PermissionServiceImpl implements PermissionService {
        @Autowired
        private PermissionDao permissionDao;
    
        /**
         * 删除权限
         * @param id
         * @throws Exception
         */
        @Override
        public void deletePermission(Integer id) throws Exception {
            permissionDao.deleteFromRole_PermissionByPermissionId(id);
            permissionDao.deletePermission(id);
        }
    }
    
    
  3. 编写控制层

 @Controller
 @RequestMapping("/permission")
 public class PermissionController {
     @Autowired
     private PermissionService permissionService;
 
     /**
      * 删除权限
      * @param id
      * @return
      * @throws Exception
      */
     @RequestMapping("/deletePermission.do")
     public String deletePermission(Integer id) throws Exception {
         permissionService.deletePermission(id);
         return "redirect:findAll.do";
     }
 }
 

6. 权限关联与控制

6.1 用户关联角色

6.1.1 用户关联角色流程分析

在这里插入图片描述

  1. 先查询出这个用户没有的角色信息
  2. 给用户添加角色就是向 users_role 插入数据

6.1.2 实现用户关联角色操作

  1. 编写持久层接口

    @Repository
    public interface UserDao {
    
        /**
         * 获取可以添加的角色信息
         *
         * @param id
         * @return
         */
        @Select("select * from role where id not in (select roleId from users_role where usersId = #{id})")
        List<Role> findOtherRole(Integer id) throws Exception;
    
        /**
         * 给用户添加角色
         *
         * @param userId
         * @param id
         * @throws Exception
         */
        @Insert("insert into users_role values(#{userId},#{id})")
        void addRoleToUser(@Param("userId") Integer userId, @Param("id") Integer id) throws Exception;
    }
    
  2. 编写业务层接口和实现类

    public interface UserService extends UserDetailsService {
    
        /**
         * 获取可以添加的角色信息
         * @param id
         * @return
         * @throws Exception
         */
        List<Role> findOtherRole(Integer id) throws Exception;
    
        /**
         * 给用户添加角色
         * @param userId
         * @param ids
         */
        void addRoleToUser(Integer userId, Integer[] ids) throws Exception;
    }
    
    
    @Transactional
    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        /**
         * 获取可以添加的角色信息
         *
         * @param id
         * @return
         * @throws Exception
         */
        @Override
        public List<Role> findOtherRole(Integer id) throws Exception {
            return userDao.findOtherRole(id);
        }
    
        /**
         * 给用户添加角色
         *
         * @param userId
         * @param ids
         */
        @Override
        public void addRoleToUser(Integer userId, Integer[] ids) throws Exception{
            for (Integer id : ids) {
                userDao.addRoleToUser(userId, id);
            }
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        private UserService userService;
    
        /**
         * 查找要添加角色的用户,及可以添加的角色
         *
         * @param id 用户 id
         * @return
         * @throws Exception
         */
        @RequestMapping("/findUserByIdAndAllRole.do")
        public ModelAndView findUserByIdAndAllRole(Integer id) throws Exception {
            ModelAndView modelAndView = new ModelAndView();
            UserInfo user = userService.findById(id);
            List<Role> roleList = userService.findOtherRole(id);
            modelAndView.addObject("user", user);
            modelAndView.addObject("roleList", roleList);
            modelAndView.setViewName("user-role-add");
            return modelAndView;
        }
    
        /**
         * 给用户添加角色
         * @param userId
         * @param ids
         * @return
         */
        @RequestMapping("/addRoleToUser.do")
        public String addRoleToUser(Integer userId, Integer[] ids) throws Exception {
            userService.addRoleToUser(userId, ids);
            return "redirect:findAll.do";
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 user-role-add.jsp

6.2 角色关联权限

6.2.1 角色关联权限流程分析

  1. 先查询出这个角色没有的权限信息
  2. 给角色添加权限就是向 role_permission 插入数据

6.2.2 实现角色关联权限操作

  1. 编写持久层接口

    @Repository
    public interface RoleDao {
    
        /**
         * 获取可以添加的权限信息
         *
         * @param id
         * @return
         * @throws Exception
         */
        @Select("select * from permission where id not in (select permissionId from role_permission where roleId = #{id})")
        List<Permission> findOtherPermission(Integer id) throws Exception;
    
        /**
         * 给角色添加权限
         *
         * @param roleId
         * @param id
         */
        @Insert("insert into role_permission values(#{id}, #{roleId})")
        void addPermissionToRole(@Param("roleId") Integer roleId, @Param("id") Integer id) throws Exception;
    }
    
    
  2. 编写业务层接口和实现类

    public interface RoleService {
    
        /**
         * 获取可以添加的权限信息
         * @param id
         * @return
         * @throws Exception
         */
        List<Permission> findOtherPermission(Integer id) throws Exception;
    
        /**
         * 给角色添加权限
         * @param roleId
         * @param ids
         * @throws Exception
         */
        void addPermissionToRole(Integer roleId, Integer[] ids) throws Exception;
    }
    
    
    @Transactional
    @Service("roleService")
    public class RoleServiceImpl implements RoleService {
        @Autowired
        private RoleDao roleDao;
    
        /**
         * 获取可以添加的权限信息
         * @param id
         * @return
         * @throws Exception
         */
        @Override
        public List<Permission> findOtherPermission(Integer id) throws Exception {
            return roleDao.findOtherPermission(id);
        }
    
        /**
         * 给角色添加权限
         * @param roleId
         * @param ids
         * @throws Exception
         */
        @Override
        public void addPermissionToRole(Integer roleId, Integer[] ids) throws Exception {
            for (Integer id : ids) {
                roleDao.addPermissionToRole(roleId,id);
            }
        }
    }
    
    
  3. 编写控制层

    @Controller
    @RequestMapping("/role")
    public class RoleController {
        @Autowired
        private RoleService roleService;
    
        /**
         * 查找要添加权限的角色,及可以添加的权限
         *
         * @param id
         * @return
         */
        @RequestMapping("/findRoleByIdAndAllPermission.do")
        public ModelAndView findRoleByIdAndAllPermission(Integer id) throws Exception {
            ModelAndView modelAndView = new ModelAndView();
            Role role = roleService.findById(id);
            List<Permission> permissionList = roleService.findOtherPermission(id);
            modelAndView.addObject("role", role);
            modelAndView.addObject("permissionList", permissionList);
            modelAndView.setViewName("role-permission-add");
            return modelAndView;
        }
    
        /**
         * 给角色添加权限
         * @param roleId
         * @param ids
         * @return
         * @throws Exception
         */
        @RequestMapping("/addPermissionToRole.do")
        public String addPermissionToRole(Integer roleId, Integer[] ids) throws Exception {
            roleService.addPermissionToRole(roleId, ids);
            return "redirect:findAll.do";
        }
    }
    
    
  4. 编写 JSP 页面

    在 pages 包中创建 role-permission-add.jsp

6.3 服务器端方法级权限控制

在服务器端我们可以通过 Spring Security 提供的注解来对方法进行权限控制。Spring Security 在方法的权限控制上支持三种类型的注解,JSR-250 注解@Secured 注解支持表达式的注解

下面介绍 JSR-250 注解的使用,其他两种注解与之类似。

6.3.1 JSR-250 注解的使用

  1. 导入 JSR-250 的依赖

    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>jsr250-api</artifactId>
        <version>1.0</version>
    </dependency>
    
  2. 在 spring-security.xml 中开启 JSR-250 注解

    <!--开启 JSR-250 注解使用-->
    <security:global-method-security jsr250-annotations="enabled"/>
    
  3. 在 controller 中指定的方法上使用 JSR-250 注解

    /**
     * 查询所有用户
     *
     * @return
     * @throws Exception
     */
    @RequestMapping("/findAll.do")
    @RolesAllowed("ADMIN")
    public ModelAndView findAll() throws Exception {
        ModelAndView modelAndView = new ModelAndView();
        List<UserInfo> users = userService.findAll();
        modelAndView.addObject("userList", users);
        modelAndView.setViewName("user-list");
    
        return modelAndView;
    }
    

6.4 页面端权限控制

6.4.1 authentication 标签

  1. 作用

    获取当前正在操作的用户信息

  2. 使用步骤

    1. 导入依赖

      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-taglibs</artifactId>
          <version>${spring.security.version}</version>
      </dependency>
      
    2. 配置 spring-security.xml

      <!--开启表达式的权限控制-->
      <bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
      
      
    3. 在 jsp 页面导入

      <%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
      
    4. 在 JSP 中获取正在操作的用户信息

      <security:authentication property="principal.username"></security:authentication>
      

6.4.2 authorize 标签

  1. 作用

    用于控制页面上的标签是否有权限显示

  2. 使用步骤

    1. 导入依赖

      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-taglibs</artifactId>
          <version>${spring.security.version}</version>
      </dependency>
      
    2. 配置 spring-security.xml

      <!--开启表达式的权限控制-->
      <bean id="webexpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
      
      
    3. 在 jsp 页面导入

      <%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
      
    4. 在 JSP 中控制页面上的标签是否有权限显示

      <security:authorize access="hasRole('ADMIN')"></security:authorize>
      
发布了64 篇原创文章 · 获赞 20 · 访问量 6487

猜你喜欢

转载自blog.csdn.net/bm1998/article/details/102826003
今日推荐