Apache Shiro最新版本1.9.1教程
配套源码Demo下载地址(建议先下载,配合教程使用,遇到问题留言):SpringBoot+ApacheShiro1.9.1最新版本详细教程,基于RBAC角色访问、安全管理框架、用户角色权限-Java文档类资源-优快云下载
先抛出一个思考问题:
很多的用户、角色、权限时候该如何管理?
希望:成熟的安全框架又能灵活的按照自己所需进行设计,快速效率全面的完成任务。
例如:
用户登陆某管理后台后,如何判断当前用户哪些菜单可见?哪些菜单中的操作可实施呢?
不做这些验证会出现什么问题?
操作安全、数据安全、网络安全等问题
-
shiro 是什么?
Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API
Apache Shiro是一个功能强大且易于使用的 Java 安全框架,它执行身份验证、授权、加密和会话管理。借助 Shiro 易于理解的 API,您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程序。
-
shiro有哪些特点?使用shiro又能够做些什么呢?
优点:快速上手、全面支持验证、授权、加密和会话、灵活自定义设计、支持web环境、可以无缝集成spring等优点。可以用来用户验证、用户授权、用户session管理、安全加密等......
特点:
全面:authentication, authorization, cryptography, and session management.
使用简单:核心的组建使用并不多,可以快速掌握。
灵活:自定义用户、角色、权限的一些体系设计
web支持:REST接口注解、url的权限字段控制config中
无缝集成:shiro starter直接集成Spring boot
能力信用背书:apache基金会
Shiro 不会去维护用户、维护权限;这些需要我们自己去设计提供(RBAC Role-Based Ac cess Control,基于角色的访问控制 );然后通过相应的接口注入给 Shiro .
-
shiro的架构设计(shiro重在理解流程原理并熟练使用)
shiro内部架构实现
• Subject:任何可以与应用交互的“用户/主体”;
• SecurityManager :相当于SpringMVC 中的 DispatcherServlet;是 Shiro 的心脏;所有具体的交互都通过 SecurityManager 进行控制;它管理着所有 Subject、且负责进行认证、授权、会话及缓存的管理。
• Authenticator:负责 Subject 认证,是一个扩展点,可以自定义实现;可以使用认证策略(Authentication Strategy),即什么情况下算用户认证通过了;
• Authorizer:授权器、即访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能;
• Realm:可以有 1 个或多个 Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC 实现,也可以是内存实现等等;由用户提供;所以一般在应用中都需要实现自己的 Realm;(授权、认证)
• SessionManager:管理 Session 生命周期的组件;而 Shiro 并不仅仅可以用在 Web环境,也可以用在如普通的 JavaSE 环境
• CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少改变,放到缓存中后可以提高访问的性能
• Cryptography:密码模块,Shiro 提高了一些常见的加密组件用于如密码加密/解密。
shiro基本内部架构所提供的功能
-
Au then ti ca tion:身份认证 / 登录,验证用户是不是拥有相应的身份;
-
Au tho ri za tion:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
-
Session Management:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;
-
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
-
Web Support:Web 支持,可以非常容易的集成到 Web 环境;
-
Caching:缓存,比如用户登录后,其用户信息、拥有的角色 / 权限不必每次去查,这样可以提高效率;
-
Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
-
Testing:提供测试支持;
-
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
-
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了
-
shiro有哪些特点?使用shiro又能够做些什么呢?
优点:快速上手、全面支持验证、授权、加密和会话、灵活自定义设计、支持web环境、可以无缝集成spring等优点。可以用来用户验证、用户授权、用户session管理、安全加密等......
Shiro 不会去维护用户、维护权限;这些需要我们自己去设计提供(RBAC Role-Based Ac cess Control,基于角色的访问控制 );然后通过相应的接口注入给 Shiro .
-
shiro的架构核心组成都有哪些东西?
重点原理流程
·
-
Subject:
主体对象,对其所有交互都会委托给SecurityManager。例如:张三
-
SecurityManager:
安全管理器,与安全有关的操作进行操作处理,SecurityManager 要验证用户身份,需要从 Realm 获取比较确定。例如:张三是否登陆有效
-
Realm:
安全域(安全数据信息,如用户、角色、权限)。例如:这里存储着张三的安全数据信息
-
如何使shiro
-
技术选型(全部最新)
springboot
shiro
mybatis
mybatis plus
mysql
thymeleaf
-
实现功能:
登陆认证、
密码加密、
权限授权、
-
基于角色访问控制RBAC建表sql:
用户表 tb_user
角色表tb_role
权限表tb_permission
用户角色表tb_user_role
角色权限tb_role_permission
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tb_permission
-- ----------------------------
DROP TABLE IF EXISTS `tb_permission`;
CREATE TABLE `tb_permission` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '权限编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='权限表';
-- ----------------------------
-- Records of tb_permission
-- ----------------------------
BEGIN;
INSERT INTO `tb_permission` VALUES (1, 'user:add');
INSERT INTO `tb_permission` VALUES (2, 'user:update');
INSERT INTO `tb_permission` VALUES (3, 'user:query');
COMMIT;
-- ----------------------------
-- Table structure for tb_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_role`;
CREATE TABLE `tb_role` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '角色名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='角色表';
-- ----------------------------
-- Records of tb_role
-- ----------------------------
BEGIN;
INSERT INTO `tb_role` VALUES (1, 'admin');
INSERT INTO `tb_role` VALUES (2, 'user');
INSERT INTO `tb_role` VALUES (3, 'superadmin');
COMMIT;
-- ----------------------------
-- Table structure for tb_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `tb_role_permission`;
CREATE TABLE `tb_role_permission` (
`id` bigint NOT NULL AUTO_INCREMENT,
`role_id` bigint DEFAULT NULL COMMENT '角色编号',
`permission_id` bigint DEFAULT NULL COMMENT '权限编号',
`permission_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COMMENT='角色权限表';
-- ----------------------------
-- Records of tb_role_permission
-- ----------------------------
BEGIN;
INSERT INTO `tb_role_permission` VALUES (4, 1, 1, 'user:add');
INSERT INTO `tb_role_permission` VALUES (5, 3, 2, 'user:update');
INSERT INTO `tb_role_permission` VALUES (6, 1, 3, 'user:query');
INSERT INTO `tb_role_permission` VALUES (7, 3, 1, 'user:add');
INSERT INTO `tb_role_permission` VALUES (8, 3, 3, 'user:query');
COMMIT;
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL COMMENT '用户名',
`password` varchar(100) DEFAULT NULL COMMENT '密码',
`salt` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1547863866599714819 DEFAULT CHARSET=utf8 COMMENT='用户表\n';
-- ----------------------------
-- Records of tb_user
-- ----------------------------
BEGIN;
INSERT INTO `tb_user` VALUES (1547617365042642946, 'zhangquancheng', '120f857f67a88a65c88aa67a7ba1923e', 'vBtmuh5Utid6okp5jOuiuA==');
INSERT INTO `tb_user` VALUES (1547863866599714818, 'superadmin', 'a938338a6e1d2f23afe233351a1c0dc5', 'pCVOU0u0TEtJ3uqNm4IDvw==');
COMMIT;
-- ----------------------------
-- Table structure for tb_user_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_user_role`;
CREATE TABLE `tb_user_role` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint DEFAULT NULL COMMENT '用户编号',
`role_id` bigint DEFAULT NULL COMMENT '角色编号',
`role_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='用户角色表';
-- ----------------------------
-- Records of tb_user_role
-- ----------------------------
BEGIN;
INSERT INTO `tb_user_role` VALUES (4, 1547617365042642946, 1, 'admin');
INSERT INTO `tb_user_role` VALUES (5, 1547863866599714818, 3, 'superadmin');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
-
Maven依赖
<!-- starter-thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.7.1</version>
</dependency>
<!-- shiro-spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.9.1</version>
</dependency>
<!-- mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.1.0</version>
</dependency>
<!-- org.projectlombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
-
项目配置文件
server: port: 8801 spring: datasource: username: root password: rootroot url: jdbc:mysql://localhost:3306/shiro?useSSL=true&useUnicode=true&characterEncoding=UTF-8 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: type-aliases-package: com.zhangquancheng.shirodemo.entity mapper-locations: classpath:mapper/*.xml
-
表对象类
@Data @AllArgsConstructor @NoArgsConstructor public class TbUser { private Long id; private String username; private String password; private String salt; } @Data @AllArgsConstructor @NoArgsConstructor public class TbRole { private Long id; private String name; } @Data @AllArgsConstructor @NoArgsConstructor public class TbPermission { private Long id; private String name; } @Data @AllArgsConstructor @NoArgsConstructor public class TbUserRole { private Long id; private Long userId; private Long roleId; private String roleName; } @Data @AllArgsConstructor @NoArgsConstructor public class TbRolePermission { private Long id; private Long roleId; private Long permissionId; private String permissionName; }
-
controlle方法入口类
@Controller public class LoginController { /** * @Description 登陆页面 */ @RequestMapping({"/toLogin","/"}) public String toLogin(Model model){ return "login"; } }
-
登陆页面login.html
<!DOCTYPE html> <!--引入thymeleaf空间约束,可以提示--> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>login</title> </head> <body style="text-align: center"> <!--/*@thymesVar id="message" type="java.lang.String"*/--> <h1>登陆</h1> <hr> <div><p th:text="${message}"></p></div> <div> <form th:action="@{/user/login}" method="post"> <div><label>userName<input type="text" name="username"/></label></div> <div><label>password<input type="password" name="password"/> </label></div> <div><input type="submit" value="Sign In"/></div> </form> </div> </body> </html>
-
项目启动测试
@SpringBootApplication //@MapperScan("com.zhangquancheng.shirodemo.mapper") public class ShiroDemoApplication { public static void main(String[] args) { SpringApplication.run(ShiroDemoApplication.class, args); } }
-
mapper类、service/impl类、XML 自动生成(略)
-
shiroConfig配置类
@Configuration @Lazy public class ShiroConfig { //ShiroFilterFactoryBean //DefaultWebSecurityManager //UserRealm // /** // * 异常映射解析器 // * // * SimpleMappingExceptionResolver 启动是在tomcat启动的时候执行 // * MyExceptionHandler 每次url访问的时候启动 // */ // @Bean // public SimpleMappingExceptionResolver simpleMappingExceptionResolver() { // SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver(); // Properties properties = new Properties(); // /*未授权处理页*/ // properties.setProperty("org.apache.shiro.authz.UnauthorizedException", "/403"); // /*⾝份没有验证*/ // properties.setProperty("org.apache.shiro.authz.UnauthenticatedException", "/toLogin"); // resolver.setExceptionMappings(properties); // return resolver; // } // /** // * Session Manager:会话管理 // * 即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中; // * 会话可以是普通JavaSE环境的,也可以是如Web环境的; // * 管理所有Subject的session包括创建、维护、删除、失效、验证等工作 // * // * DefaultSessionManager 用于JavaSE环境 // * ServletContainerSessionManager 用于Web环境,直接使用servlet容器的会话。 // * DefaultWebSessionManager 用于web环境自己维护会话 // */ // @Bean("sessionManager") // public SessionManager sessionManager(){ // DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); // sessionManager. // //设置session过期时间 // sessionManager.setGlobalSessionTimeout(60 * 60 * 1000); // sessionManager.setSessionValidationSchedulerEnabled(true); // // 去掉shiro登录时url里的JSESSIONID // sessionManager.setSessionIdUrlRewritingEnabled(false); // return sessionManager; // } /** * ShiroFilter是整个Shiro的入口点,用于拦截需要安全控制的请求进行处理 */ @Bean(name = "shiroFilter") public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); //设置安全管理器 shiroFilter.setSecurityManager(securityManager); //登陆请求 shiroFilter.setLoginUrl("/toLogin"); /** * 拦截设置 * anon:无需认证就可以访问 * authc:必须认证了才可以访问 * user:必须拥有记住我功能才能用 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色权限才能访问 * */ Map<String, String> filterMap = new LinkedHashMap<>(); //当前请求地址必须认证后访问 filterMap.put("/user/login","anon"); filterMap.put("/user/*","authc"); shiroFilter.setFilterChainDefinitionMap(filterMap); return shiroFilter; } /** * SecurityManager:安全管理器 */ @Bean(name = "securityManager") // public DefaultWebSecurityManager securityManager(@Qualifier("sessionManager") SessionManager sessionManager,@Qualifier("userRealm") UserRealm userRealm) { public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //设置realm securityManager.setRealm(userRealm); //设置会话管理sessionManager // securityManager.setSessionManager(sessionManager); return securityManager; } //第一步:创建realm对象,并被Spring托管 @Bean(name = "userRealm") public UserRealm userRealm() { UserRealm userRealm = new UserRealm(); //指定处理加解密的匹配工具类 HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5"); hashedCredentialsMatcher.setHashIterations(1); userRealm.setCredentialsMatcher(hashedCredentialsMatcher); return userRealm; } //-------------------------------------开启shiro注解 /** * 管理Shiro中一些bean的生命周期 */ @Bean("lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * 扫描上下文,寻找所有的Advistor(通知器) * 将这些Advisor应用到所有符合切入点的Bean中。 */ @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator(); proxyCreator.setProxyTargetClass(true); return proxyCreator; } /** * 匹配所有加了 Shiro 认证注解的方法 */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(securityManager); return advisor; } /** * 配置ShiroDialect:用于thymeleaf和shiro标签配合使用 */ @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } }
-
realm配置类
public class UserRealm extends AuthorizingRealm { @Autowired TbUserRoleMapper tbUserRoleMapper; @Autowired TbRolePermissionMapper tbRolePermissionMapper; @Autowired TbUserMapper tbUserMapper; /** * @Description 授权 权限匹配 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("AuthorizationInfo -----------授权"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //拿到当前登录的这个对象 Subject subject = SecurityUtils.getSubject(); TbUser currentUsers = (TbUser) subject.getPrincipal(); //获取角色 QueryWrapper queryWrapper = new QueryWrapper<TbUserRole>(); queryWrapper.select().eq("user_id",currentUsers.getId()); List<TbUserRole> tbUserRoles = tbUserRoleMapper.selectList(queryWrapper); //获取权限 queryWrapper = new QueryWrapper<TbRolePermission>(); queryWrapper.select().in("role_id",tbUserRoles.stream().map(TbUserRole::getRoleId).collect(Collectors.toList())); List<TbRolePermission> tbRolePermissions = tbRolePermissionMapper.selectList(queryWrapper); //设置角色与权限 info.setRoles(tbUserRoles.stream().map(i->i.getRoleName()).collect(Collectors.toSet())); info.setStringPermissions(tbRolePermissions.stream().map(i->i.getPermissionName()).collect(Collectors.toSet())); return info; } /** * @Description 认证 账号密码匹配(登陆) */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("AuthorizationInfo -----------认证"); //用户名,密码,从数据库中取 UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken; QueryWrapper queryWrapper = new QueryWrapper<TbUser>(); queryWrapper.select("id","password","username","salt").eq("username",userToken.getUsername()); TbUser dbuser = tbUserMapper.selectOne(queryWrapper); //不存在这个用户 if (Objects.isNull(dbuser)) { //throw new UnknownAccountException("不存在用户"); return null; } //密码认证,shiro去做 return new SimpleAuthenticationInfo(dbuser, dbuser.getPassword(), ByteSource.Util.bytes(dbuser.getSalt()),this.getName()); } }
-
异常捕获跳转页面。
-
@ControllerAdvice//controller增强器,捕获controller异常 public class MyExcetionHandler { @ExceptionHandler(UnauthorizedException.class) public String handlerUnauthorizedException(UnauthorizedException exception){ System.err.println("handlerUnauthorizedException"); exception.printStackTrace(); return "/403"; } // @RequestBody @ExceptionHandler(UnauthenticatedException.class) public String unauthenticatedException(UnauthenticatedException exception){ System.err.println("UnauthenticatedException"); exception.printStackTrace(); return "/toLogin"; } }
-
shiro异常种类 && shiro thymeleaf的常见标签:
shiro的常见异常 1.1 AuthenticationException 异常是Shiro在登录认证过程中,认证失败需要抛出的异常。 AuthenticationException包含以下⼦类: 1.1.1 CredentitalsException 凭证异常IncorrectCredentialsException 不正确的凭证ExpiredCredentialsException 凭证过期 1.1.2 AccountException 账号异常 ConcurrentAccessException 并发访问异常(多个⽤户同时登录时抛出) UnknownAccountException 未知的账号 ExcessiveAttemptsException 认证次数超过限制DisabledAccountException 禁⽤的账号 LockedAccountException 账号被锁定 pportedTokenException 使⽤了不⽀持的Token 1.2AuthorizationException: 包含⼦类: 1.2.1 UnauthorizedException:抛出以指⽰请求的操作或对请求的资源的访问是不允许的。 1.2.2 UnanthenticatedException:当尚未完成成功认证时,尝试执⾏授权操作时引发异常。
<!-- shiro thymeleaf标签的含义--> <!-- shiro:principal 当前用户的登录信息,用户名之类--> <!-- shiro:guest="" 验证是否是游客,即未认证的用户--> <!-- shiro:user="" 验证是否是已认证或已记住用户--> <!-- shiro:authenticated="" 验证是否是已认证用户,不包括已记住用户--> <!-- shiro:notAuthenticated= “” 未认证用户,但是 已记住用户--> <!-- shiro:lacksRole=“admin” 表示没有 admin 角色的用户--> <!-- shiro:hasAllRoles=“admin, user1” 表示需要同时拥有两种角色--> <!-- shiro:hasAnyRoles=“admin, user1” 表示 拥有其中一个角色即可--> <!-- shiro:lacksPermission=“admin:delete” 类似于 shiro:lacksRole--> <!-- shiro:hasAllPermissions=“admin:delete, admin:edit” 类似于 shiro:hasAllRoles--> <!-- shiro:hasAnyPermission=“admin:delete, admin:edit” 类似于 hasAnyRoles-->
-
登陆后的首页
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body style="text-align: center"> <!--/*@thymesVar id="message" type="String"*/--> <h1 th:text="${message}"></h1> <hr> <!-- 标签 含义--> <!-- shiro:principal 当前用户的登录信息,用户名之类--> <!-- shiro:guest="" 验证是否是游客,即未认证的用户--> <!-- shiro:user="" 验证是否是已认证或已记住用户--> <!-- shiro:authenticated="" 验证是否是已认证用户,不包括已记住用户--> <!-- shiro:notAuthenticated= “” 未认证用户,但是 已记住用户--> <!-- shiro:lacksRole=“admin” 表示没有 admin 角色的用户--> <!-- shiro:hasAllRoles=“admin, user1” 表示需要同时拥有两种角色--> <!-- shiro:hasAnyRoles=“admin, user1” 表示 拥有其中一个角色即可--> <!-- shiro:lacksPermission=“admin:delete” 类似于 shiro:lacksRole--> <!-- shiro:hasAllPermissions=“admin:delete, admin:edit” 类似于 shiro:hasAllRoles--> <!-- shiro:hasAnyPermission=“admin:delete, admin:edit” 类似于 hasAnyRoles--> <!-- <shiro:hasRole name="admin">--> <shiro:hasAnyRoles name="admin,superadmin"> <a href="#" th:href="@{/user/admin}" class="ui mini teal basic button">管理员菜单</a> </shiro:hasAnyRoles> <a href="#" th:href="@{/user/open}" class="ui mini teal basic button">用户菜单</a> </body> </html>
-
开放页面(仅让超级管理员进入)
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>open</title> </head> <body> <!--/*@thymesVar id="message" type="String"*/--> <h1 th:text="${message}"></h1> </hr> </body> </html>
-
无权限页面
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>success</title> </head> <body> <!--/*@thymesVar id="message" type="String"*/--> 对不起无权限 <h1 th:text="${message}"></h1> </hr> </body> </html>
-
操作成功页面
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>success</title> </head> <body> <!--/*@thymesVar id="message" type="String"*/--> <h1 th:text="${message}"></h1> </hr> </body> </html>
-
相关文档介绍
官方文档:10分钟快速开始
中文资料:w3c介绍
-
-
-
-
-
-