原无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限
Posted iflytek
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限相关的知识,希望对你有一定的参考价值。
上一篇《【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限》介绍了实现Shiro的基础认证。本篇谈谈实现Shiro的基础授权。
需求:
① 某系统有公共模块、领导模块、管理员模块三个业务模块,均需要登录系统后才可以访问。
② admin、leader、employee三个人职位分别是管理员、领导、员工,均可登录系统。
③ 不同职位的人登录系统后,能看到的功能模块不同。管理员可以访问全部三个模块。领导可以访问除去管理员模块外的两个模块。员工只能访问公共模块。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
分析:
典型的运用授权权限的需求,继续考虑使用Shiro。
问题1、认证和授权怎么理解呢?
答:一点粗浅理解,比如通过了美国的签证能进入美国了,这就是获得了认证。
但是进入美国了,也只能去有授权的地方玩玩,五角大楼能进么?没有授权是不给进的。
所以,授权是在认证获得后进一步的安全管理。
问题2、需求在描述什么场景?
答:需求中包含了基于角色的权限访问控制RBAC(Role-Based Access Control)的设计思路。
简单来说,单个人对某某资源可操作。
进一步考虑,如果是多个人对某某资源可操作呢?需要重复的这样设置么?运用归纳思想,把这样的多个人归为一类,形成了角色的概念。即这一角色的多个人对某某资源可操作。
RBAC认为权限授权实际上是Who、What、How的问题。在RBAC模型中,who、what、how构成了访问权限三元组,也就是“Who对What(Which)进行How的操作”。
问题3、针对本需求的RBAC设计是怎么样的?
答:简化设计为:用户和角色为多对一关系、角色和资源为多对多关系
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0、数据库建表init.sql
1 -- 初始化 2 DROP TABLE sys_user; 3 DROP TABLE sys_role; 4 DROP TABLE sys_resource; 5 DROP TABLE sys_role_resource; 6 7 -- 用户信息表 8 CREATE TABLE sys_user 9 ( 10 userid INT AUTO_INCREMENT PRIMARY KEY COMMENT \'用户编号\', 11 username VARCHAR(10) NOT NULL COMMENT \'用户名称\', 12 `password` VARCHAR(10) NOT NULL COMMENT \'用户密码\', 13 roleid INT NOT NULL COMMENT \'角色编号\' 14 ); 15 16 INSERT INTO sys_user VALUES(NULL, \'admin\', \'123\', 1), (NULL, \'leader\', \'456\', 2), (NULL, \'employee\', \'789\', 3); 17 18 SELECT * FROM sys_user; 19 20 -- 角色信息表 21 CREATE TABLE sys_role 22 ( 23 roleid INT AUTO_INCREMENT PRIMARY KEY COMMENT \'角色编号\', 24 rolename VARCHAR(10) NOT NULL COMMENT \'角色名称\' 25 ); 26 27 INSERT INTO sys_role VALUES(NULL, \'管理员\'), (NULL, \'领导\'), (NULL, \'员工\'); 28 29 SELECT * FROM sys_role; 30 31 -- 资源信息表 32 CREATE TABLE sys_resource 33 ( 34 resourceid INT AUTO_INCREMENT PRIMARY KEY COMMENT \'资源编号\', 35 resourcename VARCHAR(10) NOT NULL COMMENT \'资源名称\', 36 resourceurl VARCHAR(50) NOT NULL COMMENT \'资源URL\' 37 ); 38 39 INSERT INTO sys_resource VALUES 40 (NULL, \'公共模块\', \'publicModule\'), 41 (NULL, \'领导模块\', \'leaderModule\'), 42 (NULL, \'管理员模块\', \'adminModule\'); 43 44 SELECT * FROM sys_resource; 45 46 -- 角色资源关联表 47 CREATE TABLE sys_role_resource 48 ( 49 id INT AUTO_INCREMENT PRIMARY KEY COMMENT \'关联编号\', 50 roleid INT NOT NULL COMMENT \'角色编号\', 51 resourceid INT NOT NULL COMMENT \'资源编号\' 52 ); 53 54 INSERT INTO sys_role_resource VALUES 55 (NULL, 1, 1), (NULL, 1, 2), (NULL, 1, 3), 56 (NULL, 2, 1), (NULL, 2, 2), 57 (NULL, 3, 1); 58 59 SELECT * FROM sys_role_resource; 60 61 -- 获取用户能访问的资源URL 62 SELECT u.userid, rs.resourceurl 63 FROM sys_role_resource AS rr 64 INNER JOIN sys_resource AS rs ON rr.resourceid = rs.resourceid 65 INNER JOIN sys_role AS r ON rr.roleid = r.roleid 66 INNER JOIN sys_user AS u ON u.roleid = r.roleid 67 WHERE u.userid = 1;
1、编写项目对象模型文件pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>cn.temptation</groupId> 8 <artifactId>studyShiro</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>2.0.4.RELEASE</version> 15 </parent> 16 17 <dependencies> 18 <!-- web --> 19 <dependency> 20 <groupId>org.springframework.boot</groupId> 21 <artifactId>spring-boot-starter-web</artifactId> 22 </dependency> 23 <!-- thymeleaf --> 24 <dependency> 25 <groupId>org.springframework.boot</groupId> 26 <artifactId>spring-boot-starter-thymeleaf</artifactId> 27 </dependency> 28 <!-- spring data jpa --> 29 <dependency> 30 <groupId>org.springframework.boot</groupId> 31 <artifactId>spring-boot-starter-data-jpa</artifactId> 32 </dependency> 33 <!-- mariadb --> 34 <dependency> 35 <groupId>org.mariadb.jdbc</groupId> 36 <artifactId>mariadb-java-client</artifactId> 37 <version>2.2.5</version> 38 </dependency> 39 <!-- shiro --> 40 <dependency> 41 <groupId>org.apache.shiro</groupId> 42 <artifactId>shiro-spring</artifactId> 43 <version>1.4.0</version> 44 </dependency> 45 <!-- thymeleaf-extras-shiro --> 46 <dependency> 47 <groupId>com.github.theborakompanioni</groupId> 48 <artifactId>thymeleaf-extras-shiro</artifactId> 49 <version>2.0.0</version> 50 </dependency> 51 <!-- 热启动 --> 52 <dependency> 53 <groupId>org.springframework.boot</groupId> 54 <artifactId>spring-boot-devtools</artifactId> 55 <optional>true</optional> 56 </dependency> 57 </dependencies> 58 </project>
2、编写项目配置文件application.properties
1 # 数据库访问配置 2 # 对应MariaDB驱动 3 spring.datasource.driverClassName=org.mariadb.jdbc.Driver 4 5 # 数据源配置 6 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test 7 spring.datasource.username=root 8 spring.datasource.password=sa 9 10 # 配置Springboot默认支持的Hikari数据库连接池 11 spring.datasource.type=com.zaxxer.hikari.HikariDataSource 12 spring.datasource.hikari.minimum-idle=5 13 spring.datasource.hikari.maximum-pool-size=15 14 spring.datasource.hikari.auto-commit=true 15 spring.datasource.hikari.idle-timeout=30000 16 spring.datasource.hikari.pool-name=DatebookHikariCP 17 spring.datasource.hikari.max-lifetime=1800000 18 spring.datasource.hikari.connection-timeout=30000 19 spring.datasource.hikari.connection-test-query=SELECT 1 20 21 # Spring Data JPA配置 22 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 23 spring.jpa.properties.hibernate.hbm2ddl.auto=update 24 spring.jpa.show-sql=true 25 spring.jpa.properties.hibernate.format_sql=true 26 27 # 格式化输出的json字符串 28 spring.jackson.serialization.indent_output=true 29 30 # 设置控制台彩色打印 31 spring.output.ansi.enabled=ALWAYS
3、编写项目启动类Application.java
1 package cn.temptation; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 6 @SpringBootApplication 7 public class Application { 8 public static void main(String[] args) { 9 // SpringBoot项目启动 10 SpringApplication.run(Application.class, args); 11 } 12 }
4、编写全局异常处理类GlobalExceptionHandler.java
1 package cn.temptation.util; 2 3 import org.springframework.web.bind.annotation.ControllerAdvice; 4 import org.springframework.web.bind.annotation.ExceptionHandler; 5 6 /** 7 * 全局异常处理类 8 */ 9 @ControllerAdvice 10 public class GlobalExceptionHandler { 11 @ExceptionHandler(value = Exception.class) 12 public String errorHandler(Exception exception) { 13 return "redirect:/error/500"; 14 } 15 }
5、编写错误页配置类ErrorPageConfig.java 和 错误页控制器ErrorController.java
错误页配置类ErrorPageConfig.java
1 package cn.temptation.util; 2 3 import org.springframework.boot.web.server.ErrorPage; 4 import org.springframework.boot.web.server.ErrorPageRegistrar; 5 import org.springframework.boot.web.server.ErrorPageRegistry; 6 import org.springframework.http.HttpStatus; 7 import org.springframework.stereotype.Component; 8 9 /** 10 * 错误页配置类 11 */ 12 @Component 13 public class ErrorPageConfig implements ErrorPageRegistrar { 14 @Override 15 public void registerErrorPages(ErrorPageRegistry errorPageRegistry) { 16 // 错误类型为401(无访问权限),显示401.html页面 17 ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401"); 18 19 // 错误类型为404(找不到资源),显示404.html页面 20 ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"); 21 22 // 错误类型为500(服务器内部错误),显示500.html页面 23 ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"); 24 25 errorPageRegistry.addErrorPages(errorPage401, errorPage404, errorPage500); 26 } 27 }
错误页控制器ErrorController.java
1 package cn.temptation.util; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.GetMapping; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 7 /** 8 * 错误页控制器 9 */ 10 @Controller 11 @RequestMapping("/error") 12 public class ErrorController { 13 // 401页面 14 @GetMapping(value = "/401") 15 public String error_401() { 16 return "error/error_401"; 17 } 18 19 // 404页面 20 @GetMapping(value = "/404") 21 public String error_404() { 22 return "error/error_404"; 23 } 24 25 // 500页面 26 @GetMapping(value = "/500") 27 public String error_500() { 28 return "error/error_500"; 29 } 30 }
6、编写错误页error_401.html、error_404.html 和 error_500.html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="refresh" content="5;URL=/login"> 6 <title>401</title> 7 <style> 8 ::-moz-selection { 9 background: #b3d4fc; 10 text-shadow: none; 11 } 12 13 ::selection { 14 background: #b3d4fc; 15 text-shadow: none; 16 } 17 18 html { 19 padding: 30px 10px; 20 font-size: 20px; 21 line-height: 1.4; 22 color: #737373; 23 background: #f0f0f0; 24 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 25 -webkit-text-size-adjust: 100%; 26 -ms-text-size-adjust: 100%; 27以上是关于原无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限的主要内容,如果未能解决你的问题,请参考以下文章
原无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页
原无脑操作:IDEA + maven + SpringBoot + JPA + EasyUI实现CRUD及分页
原无脑操作:Eclipse + Maven + jFinal + MariaDB 环境搭建