1.初始登陆代码 1.1.application.yml(配置文件) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath:mapper/* .xml spring: datasource: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/shirodb?characterEncoding=utf-8&useSSL=false username: root password: 123456 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 shiro: loginUrl: /myController/userLogin
1.2.pom.xml 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 <?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.16-SNAPSHOT</version > <relativePath /> </parent > <groupId > com.gaomu</groupId > <artifactId > spring_shiro</artifactId > <version > 0.0.1-SNAPSHOT</version > <name > spring_shiro</name > <description > spring_shiro</description > <properties > <java.version > 1.8</java.version > </properties > <dependencies > <dependency > <groupId > org.apache.shiro</groupId > <artifactId > shiro-spring-boot-web-starter</artifactId > <version > 1.9.0</version > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-thymeleaf</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.3.1</version > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <optional > true</optional > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-test</artifactId > <scope > test</scope > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.46</version > </dependency > <dependency > <groupId > com.baomidou</groupId > <artifactId > mybatis-plus-boot-starter</artifactId > <version > 3.0.5</version > </dependency > <dependency > <groupId > org.apache.shiro</groupId > <artifactId > shiro-core</artifactId > <version > 1.9.0</version > </dependency > </dependencies > <build > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > <configuration > <excludes > <exclude > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > </exclude > </excludes > </configuration > </plugin > </plugins > </build > <repositories > <repository > <id > spring-milestones</id > <name > Spring Milestones</name > <url > https://repo.spring.io/milestone</url > <snapshots > <enabled > false</enabled > </snapshots > </repository > <repository > <id > spring-snapshots</id > <name > Spring Snapshots</name > <url > https://repo.spring.io/snapshot</url > <releases > <enabled > false</enabled > </releases > </repository > </repositories > <pluginRepositories > <pluginRepository > <id > spring-milestones</id > <name > Spring Milestones</name > <url > https://repo.spring.io/milestone</url > <snapshots > <enabled > false</enabled > </snapshots > </pluginRepository > <pluginRepository > <id > spring-snapshots</id > <name > Spring Snapshots</name > <url > https://repo.spring.io/snapshot</url > <releases > <enabled > false</enabled > </releases > </pluginRepository > </pluginRepositories > </project >
1.3.ShingShiroApplication(启动主类) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.gaomu.spring_shiro;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication @MapperScan("com.gaomu.spring_shiro.mapper") public class SpringShiroApplication { public static void main (String[] args) { SpringApplication.*run*(SpringShiroApplication.class, args); } }
1.4.UserService(服务层接口) 1 2 3 4 5 6 7 8 9 package com.gaomu.spring_shiro.service;import com.gaomu.spring_shiro.entity.User;public interface UserService { User getUserInfoByName (String name) ; }
1.5.UserServoceImpl(服务层实现) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package com.gaomu.spring_shiro.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.gaomu.spring_shiro.entity.User;import com.gaomu.spring_shiro.mapper.UserMapper;import com.gaomu.spring_shiro.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User getUserInfoByName (String name) { QueryWrapper<User> wrapper = new QueryWrapper <>(); wrapper.eq("name" , name); User user = userMapper.selectOne(wrapper); return user; } }
1.6.UserMapper(数据层接口) 1 2 3 4 5 6 7 8 package com.gaomu.spring_shiro.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.gaomu.spring_shiro.entity.User;import org.springframework.stereotype.Repository;@Repository public interface UserMapper extends BaseMapper <User> {}
1.7.User(定义数据模型) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.gaomu.spring_shiro.entity;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String name; private String pwd; private Integer rid; }
1.8.ShiroConfig(shiro配置类) 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 package com.gaomu.spring_shiro.config;import com.gaomu.spring_shiro.realm.MyRealm;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration public class ShiroConfig { @Autowired private MyRealm myRealm; @Bean public DefaultWebSecurityManager defaultWebSecurityManager () { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager (); HashedCredentialsMatcher matcher = new HashedCredentialsMatcher (); matcher.setHashAlgorithmName("md5" ); matcher.setHashIterations(3 ); myRealm.setCredentialsMatcher(matcher); defaultWebSecurityManager.setRealm(myRealm); return defaultWebSecurityManager; } @Bean public DefaultShiroFilterChainDefinition shiroFilterChainDefinition () { DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition (); definition.addPathDefinition("/myController/userLogin" ,"anon" ); definition.addPathDefinition("/myController/login" , "anon" ); definition.addPathDefinition("/**" , "authc" ); return definition; } }
1.9.MyRealm(定义Realm) 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 package com.gaomu.spring_shiro.realm;import com.gaomu.spring_shiro.entity.User;import com.gaomu.spring_shiro.service.UserService;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Component public class MyRealm extends AuthorizingRealm { @Autowired private UserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) { return null ; } @Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) throws AuthenticationException { String name = authenticationToken.getPrincipal().toString(); User user = userService.getUserInfoByName(name); if (user != null ){ AuthenticationInfo info = new SimpleAuthenticationInfo ( authenticationToken.getPrincipal(), user.getPwd(), ByteSource.Util.bytes("salt" ), authenticationToken.getPrincipal().toString() ); return info; } return null ; } }
1.11.MyController(控制层) 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 package com.gaomu.spring_shiro.controller;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;@Controller @RequestMapping("myController") public class MyController { @GetMapping("userLogin") @ResponseBody public String userLogin (String name, String pwd) { Subject subject = SecurityUtils.getSubject(); AuthenticationToken token = new UsernamePasswordToken (name, pwd); try { subject.login(token); return "登陆成功" ; } catch (AuthenticationException e) { e.printStackTrace(); System.out.println("登陆失败" ); return "登陆失败" ; } } }
1.12.数据库用户表
get请求 登陆测试
2.前端实现shiro整合Thymeleaf 2.1.pom.xml(导入Thymeleaf依赖) 1 2 3 4 <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-thymeleaf</artifactId > </dependency >
2.2.application.yml (更改重定向页面) 1 2 shiro: loginUrl: /myController/login
2.2.login.html(登陆页面) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 > Shiro登录认证</h1 > <form action ="/myController/userLogin" > <div > 用户名:<input type ="text" name ="name" value ="" > </div > <div > 密码 :<input type ="password" name ="pwd" value ="" > </div > <div > <input type ="submit" value ="登录" > </div > </form > </body > </html >
2.3.index.html(登陆成功页面) 1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <h1 > shiro登录认证后主页面</h1 > <br > 登录用户为:<span th:text ="${session.user}" > </span > </body > </html >
2.4.Mycontroller 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 import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpSession;@Controller @RequestMapping("myController") public class MyController { @GetMapping("login") public String login () { return "login" ; } @GetMapping("userLogin") public String userLogin (String name, String pwd, HttpSession session) { Subject subject = SecurityUtils.getSubject(); AuthenticationToken token = new UsernamePasswordToken (name, pwd); try { subject.login(token); session.setAttribute("user" , token.getPrincipal().toString()); return "index" ; } catch (AuthenticationException e) { e.printStackTrace(); System.out.println("登陆失败" ); return "登陆失败" ; } } }
3.多realm实现 3.1.多个realm实现原理 当应用程序配置多个Realm时,例如:用户名密码校验、手机号验证码校验等等。Shiro的ModularRealmAuthenticator会使用内部的AuthenticationStrategy.组件判断认证是成功还是失败。
AuthenticationStrategy是一个无状态的组件,它在身份验证尝试中被询问4次(这4次交互所需的任何必要的状态将被作为方法参数): (1)在所有Realm被调用之前
(2)在调用Realm的 getAuthenticationInfo方法之前
(3)在调用Realm的 getAuthenticationInfo·方法之后
(4)在所有Realm被调用之后
4.remember me 4.1.简介 Shiro·提供了记住我(RememberMe)的功能,比如访问一些网站时,关闭了浏览器,下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问。
4.2.基本流程 1、基本流程 (1)首先在登录页面选中RememberMe然后登录成功;如果是浏览器登录,一般会把RememberMe_的Cookie写到客户端并保存下来;
(2)关闭浏览器再重新打开;会发现浏览器还是记住你的;
(3)访问一般的网页服务器端,仍然知道你是谁,且能正常访问;
(4)但是,如果我们访问电商平台时,如果要查看我的订单或进行支付时,此时还 是需要再进行身份认证的,以确保当前用户还是你。
4.3.ShiroConfig (添加RememberMe和用户拦截) 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 package com.gaomu.spring_shiro.config;import com.gaomu.spring_shiro.realm.MyRealm;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;import org.apache.shiro.web.mgt.CookieRememberMeManager;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.apache.shiro.web.servlet.Cookie;import org.apache.shiro.web.servlet.SimpleCookie;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration public class ShiroConfig { @Autowired private MyRealm myRealm; @Bean public DefaultWebSecurityManager defaultWebSecurityManager () { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager (); HashedCredentialsMatcher matcher = new HashedCredentialsMatcher (); matcher.setHashAlgorithmName("md5" ); matcher.setHashIterations(3 ); myRealm.setCredentialsMatcher(matcher); defaultWebSecurityManager.setRealm(myRealm); defaultWebSecurityManager.setRememberMeManager(rememberMeManager()); return defaultWebSecurityManager; } public SimpleCookie rememberMeCookie () { SimpleCookie cookie = new SimpleCookie ("rememberMe" ); cookie.setPath("/" ); cookie.setHttpOnly(true ); cookie.setMaxAge(30 *24 *60 *60 ); return cookie; } public CookieRememberMeManager rememberMeManager () { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager (); cookieRememberMeManager.setCookie(rememberMeCookie()); cookieRememberMeManager.setCipherKey("1234567891234567" .getBytes()); return cookieRememberMeManager; } @Bean public DefaultShiroFilterChainDefinition shiroFilterChainDefinition () { DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition (); definition.addPathDefinition("/myController/userLogin" ,"anon" ); definition.addPathDefinition("/myController/login" , "anon" ); definition.addPathDefinition("/**" , "authc" ); definition.addPathDefinition("/**" , "user" ); return definition; } }
4.4.MyController 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 @GetMapping("userLogin") public String userLogin (String name, String pwd, @RequestParam(defaultValue = "false") boolean rememberMe, HttpSession session) { Subject subject = SecurityUtils.getSubject(); AuthenticationToken token = new UsernamePasswordToken (name, pwd, rememberMe); try { subject.login(token); session.setAttribute("user" , token.getPrincipal().toString()); return "index" ; } catch (AuthenticationException e) { e.printStackTrace(); System.out.println("登陆失败" ); return "登陆失败" ; } } @GetMapping("userLoginRm") public String userLogin (HttpSession session) { session.setAttribute("user" , "rememberMe" ); return "index" ; }
4.5.login.html(添加记住登陆勾选框) 1 2 3 4 5 6 <form action ="/myController/userLogin" > <div > 用户名:<input type ="text" name ="name" value ="" > </div > <div > 密码 :<input type ="password" name ="pwd" value ="" > </div > <div > 记住用户:<input type ="checkbox" name ="rememberMe" value ="true" > </div > <div > <input type ="submit" value ="登录" > </div > </form >
5.用户登出 5.1.index.html 1 2 3 4 5 6 7 <body > <h1 > shiro登录认证后主页面</h1 > <br > 登录用户为:<span th:text ="${session.user}" > </span > <br > <a href ="/logout" > 登出</a > </body >
5.2.ShiroConfig 1 2 definition.addPathDefinition("/logout" , "logout" );
6.授权 用户登录后,需要验证是否具有指定角色指定权限。Shiro也提供了方便的工具进行判断。
这个工具就是Realm的doGetAuthorizationInfo方法进行判断。触发权限判断的有两种方式
(1)在页面中通过shiro :***属性判断
(2)在接口服务中通过注解@Requires***进行判断
6.1.后端接口服务注解 通过给接口服务方法添加注解可以实现权限校验,可以加在控制器方法上,也可以加在业务方法上,一般加在控制器方法上。常用注解如下:(1) @RequiresAuthenticationk 验证用户是否登录,等同于方法subject.isAuthenticated()
(2)@RequiresUserl’ 验证用户是否被记忆: 登录认证成功subject.i.sAuthenticated()为true
登录后被记忆subject.i.sRemembered()为true
(3)@RequiresGuest
验证是否是一个guest的请求,是否是游客的请求-此时subject.getPrincipal.()为nulle
(4)@RequiresRolese
验证subject是否有相应角色,有角色访问方法,没有则会抛出异常AuthorizationException。
例如:@RequiresRoles(“aRoleName”)
void someMethod();
只有subject有aRoleName角色才能访问方法someMethod()
(5) @RequiresPermissionse 验证subject是否有相应权限,有权限访问方法,没有则会抛出异常AuthorizationException。
例如:@RequiresPermissions· ( “file:read”, “wite: aFile.txt”)
void- someMethod() ;
subject必须同时含有file:read和wite:aFile.txt权限才能访问方法someMethod()
6.2.数据库角色表
6.3.UserMapper(配置查询数据库角色接口) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.gaomu.spring_shiro.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;import com.gaomu.spring_shiro.entity.User;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select;import org.springframework.stereotype.Repository;import java.util.List;@Repository public interface UserMapper extends BaseMapper <User> { @Select("SELECT name FROM role WHERE id IN (\n" + "\tSELECT rid FROM role_user WHERE uid = (\n" + "\t\tSELECT id FROM USER WHERE NAME=#{principal}\n" + "\t)\n" + ")") List<String> getUserRoleInfoMapper (@Param("principal") String principal) ; }
6.4.UserService(配置查询角色服务层接口) 1 2 List<String> getUserRoleInfo (String principal) ;
6.5.UserServiceImpl(实现查询接口) 1 2 3 4 5 @Override public List<String> getUserRoleInfo (String principal) { return userMapper.getUserRoleInfoMapper(principal); }
6.6.MyController(添加验证角色授权接口) 1 2 3 4 5 6 7 8 @RequiresRoles("admin") @GetMapping("userLoginRoles") @ResponseBody public String userLoginRoles () { System.out.println("登陆认证验证角色" ); return "验证角色成功" ; }
6.7.index.html(添加授权测试超链接) 1 2 <br> <a href="/myController/userLoginRoles" >测试授权</a>
6.8.MyRealm(配置doGet授权方法) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) { System.out.println("自定义授权方法" ); String principal = principalCollection.getPrimaryPrincipal().toString(); List<String> roles = userService.getUserRoleInfo(principal); System.out.println("当前用户角色信息:" + roles); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo (); info.addRoles(roles); return info; }
7.权限验证 7.1.建立权限表和关联表
7.2.UserMapper(通过角色信息查询权限信息) 1 2 3 4 5 6 7 8 9 10 11 12 @Select({ "<script>", "select info FROM permissions WHERE id IN ", "(SELECT pid FROM role_ps WHERE rid IN (", "SELECT id FROM role WHERE NAME IN ", "<foreach collection='roles' item='name' open='(' separator=' , ' close=')'>", "#{name}", "</foreach>", "))", "</script>" }) List<String> getUserPermissionInfoMapper (@Param("roles") List<String> roles) ;
7.3.UserService 1 2 List<String> getUserPermissionInfo (List<String> roles) ;
7.4.UserServiceImpl 1 2 3 4 5 @Override public List<String> getUserPermissionInfo (List<String> roles) { return userMapper.getUserPermissionInfoMapper(roles); }
7.5.MyRealm(添加权限信息) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) { System.out.println("自定义授权方法" ); String principal = principalCollection.getPrimaryPrincipal().toString(); List<String> roles = userService.getUserRoleInfo(principal); System.out.println("当前用户角色信息:" + roles); List<String> permissions = userService.getUserPermissionInfo(roles); System.out.println("当前用户的权限信息:" + permissions); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo (); info.addRoles(roles); info.addStringPermissions(permissions); return info; }
7.6.MyController 1 2 3 4 5 6 7 8 @RequiresPermissions("user:delete") @GetMapping("userPermissions") @ResponseBody public String userLoginPermissions () { System.out.println("登陆认证验证权限" ); return "验证权限成功" ; }
7.7.index.html 1 2 <br > <a href ="/myController/userPermissions" > 测试权限</a >
8.异常处理 8.1.PermissionsException(异常处理) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package com.gaomu.spring_shiro.controller;import org.apache.shiro.authz.AuthorizationException;import org.apache.shiro.authz.UnauthorizedException;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;@ControllerAdvice public class PermissionsException { @ResponseBody @ExceptionHandler(UnauthorizedException.class) public String unauthorizedException (Exception e) { return "无权限" ; } @ResponseBody @ExceptionHandler(AuthorizationException.class) public String authorizationException (Exception e) { return "权限认证失败" ; } }
9.前端页面显示权限处理 9.1.Thymeleaf中常用的shiro属性
shiro:guest
用户没有身份验证时显示相应信息,即游客访问信息。
用户已经身份验证/记住我登录后显示相应的信息。
shiro:authenticated
用户已经身份验证通过,即Subject.login.登录成功,不是记住我登录的。
shiro:notAuthenticated
用户已经身份验证通过,即没有调用Subject.login进行登录,包括记住我自动登录的也属于未进行身份验证。
<shiro: principal/> <shiro: principal property=”username”/>
相当于((User)Subject.getPrincipals()).getUsername()。
lacksPermission标签 <shiro:lacksPermission name=”org:create” >
如果当前Subject没有权限将显示body体内容。
hasRole标签 <shiro:hasRol.e name=”admin”>
如果当前Subject有角色将显示body体内容。
hasAnyRoles 标签 <shiro:hasAnyRoles name=”admin, user”>
如果当前Subject有任意一个角色(或的关系)将显示body体内容。
*** lacksRole标签*** <shiro: lacksRole: name=”abc”>
</shiro: lacksRole>
如果当前Subject没有角色将显示body 体内容。
hasPermission.标签 <shiro:hasPermission name=”user:create”>
如果当前Subject有权限将显示body 体内容-
9.2.pom.xml 1 2 3 4 5 <dependency > <groupId > com.github.theborakompanioni</groupId > <artifactId > thymeleaf-extras-shiro</artifactId > <version > 2.0.0</version > </dependency >
9.3.ShiroConfig 1 2 3 4 @Bean public ShiroDialect shiroDialect () { return new ShiroDialect (); }
9.4.index.html 1 2 3 4 5 6 7 <html lang ="en" xmlns:shiro ="http://www.w3.org/1999/xhtml" > ------------ <br > <a shiro:hasRole ="admin" href ="/myController/userLoginRoles" > 测试授权</a > <br > <a shiro:hasPermission ="user:delete" href ="/myController/userPermissions" > 测试权限</a >