SpringBoot+Mybatis框架整合Shiro权限管理
一、前言 之前曾分享过一个关于shiro的认证原理的文章,分享了一下shiro的认证流程与shiro中的名词解释,其实shiro作为一款轻量级框架,被应用在各种中小型及大型企业的登录认证和用户授权的模块,有小伙伴称,在用SpringBoot框架,之前用过xml方式进行配置shiro框架,问我如何使用SpringBoot+注解来进行shiro的配置,我整理了文章,供大家参考
二、搭建shiro框架 1.首先搭建SpringBoot基础工程和Mybatis整合,此步骤之前讲解过,可自行前往之前的帖子中查看 SpringBoot工程搭建
SpringBoot整合Mybatis
2.引入shiro-spring的依赖包,完整的pom文件如下 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 <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 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <groupId > com.yang.study.shiro</groupId > <artifactId > SpringBootShiro</artifactId > <version > 0.0.1-SNAPSHOT</version > <name > SpringBootShiro</name > <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 1.5.2.RELEASE</version > </parent > <dependencies > <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 > 1.2.0</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.0.29</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > </dependency > <dependency > <groupId > com.github.pagehelper</groupId > <artifactId > pagehelper</artifactId > <version > 4.1.0</version > </dependency > <dependency > <groupId > org.apache.shiro</groupId > <artifactId > shiro-spring</artifactId > <version > 1.3.2</version > </dependency > </dependencies > <build > <finalName > SpringBootShiro</finalName > <plugins > <plugin > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-maven-plugin</artifactId > </plugin > </plugins > </build > </project >
3.创建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 47 48 CREATE TABLE `permission` ( `id` bigint (20 ) NOT NULL , `permission` varchar (200 ) DEFAULT NULL , PRIMARY KEY (`id` ) ) ENGINE =InnoDB DEFAULT CHARSET =utf8 COMMENT ='权限表' ; INSERT INTO `permission` VALUES ('1' , 'user:queryUserAll' );INSERT INTO `permission` VALUES ('2' , 'user:queryById' );DROP TABLE IF EXISTS `role` ;CREATE TABLE `role` ( `id` bigint (11 ) NOT NULL , `role_name` varchar (40 ) DEFAULT NULL , PRIMARY KEY (`id` ) ) ENGINE =InnoDB DEFAULT CHARSET =utf8 COMMENT ='角色表' ; INSERT INTO `role` VALUES ('1' , 'admin' );INSERT INTO `role` VALUES ('2' , 'devlop' ); DROP TABLE IF EXISTS `role_permission` ;CREATE TABLE `role_permission` ( `role_id` bigint (20 ) DEFAULT NULL , `permission_id` bigint (20 ) DEFAULT NULL ) ENGINE =InnoDB DEFAULT CHARSET =utf8 COMMENT ='角色权限表' ; INSERT INTO `role_permission` VALUES ('1' , '1' );INSERT INTO `role_permission` VALUES ('1' , '2' );INSERT INTO `role_permission` VALUES ('2' , '2' );DROP TABLE IF EXISTS `user` ;CREATE TABLE `user` ( `id` bigint (20 ) NOT NULL , `name` varchar (40 ) DEFAULT NULL , `password` varchar (40 ) DEFAULT NULL , PRIMARY KEY (`id` ) ) ENGINE =InnoDB DEFAULT CHARSET =utf8 COMMENT ='用户表' ; INSERT INTO `user` VALUES ('1' , 'admin' , '123456' );INSERT INTO `user` VALUES ('2' , 'yang' , '123456' );DROP TABLE IF EXISTS `user_role` ;CREATE TABLE `user_role` ( `user_id` bigint (20 ) NOT NULL , `role_id` bigint (20 ) DEFAULT NULL , PRIMARY KEY (`user_id` ) ) ENGINE =InnoDB DEFAULT CHARSET =utf8 COMMENT ='用户角色表' ; INSERT INTO `user_role` VALUES ('1' , '1' );
4.生成所对应的实体bean对象(可自己编写,也可使用mybatis自动生成器 ) User对象实体类 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 package com.yang.bean;import java.io.Serializable;import java.util.List;public class User implements Serializable { private Long id; private String name; private String password; private List<Role> roles; private static final long serialVersionUID = 1L ; public Long getId () { return id; } public void setId (Long id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name == null ? null : name.trim(); } public String getPassword () { return password; } public void setPassword (String password) { this .password = password == null ? null : password.trim(); } public List<Role> getRoles () { return roles; } public void setRoles (List<Role> roles) { this .roles = roles; } }
角色Role对象实体类 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 package com.yang.bean;import java.io.Serializable;import java.util.List;public class Role implements Serializable { private Long id; private String roleName; private User user; private List<Permission> permissions; private static final long serialVersionUID = 1L ; public Long getId () { return id; } public void setId (Long id) { this .id = id; } public String getRoleName () { return roleName; } public void setRoleName (String roleName) { this .roleName = roleName == null ? null : roleName.trim(); } public User getUser () { return user; } public void setUser (User user) { this .user = user; } public List<Permission> getPermissions () { return permissions; } public void setPermissions (List<Permission> permissions) { this .permissions = permissions; } }
权限表对象Permission实体类 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 package com.yang.bean;import java.io.Serializable;public class Permission implements Serializable { private Long id; private String permission; private Role role; private static final long serialVersionUID = 1L ; public Long getId () { return id; } public void setId (Long id) { this .id = id; } public String getPermission () { return permission; } public void setPermission (String permission) { this .permission = permission == null ? null : permission.trim(); } public Role getRole () { return role; } public void setRole (Role role) { this .role = role; } }
其他两个关系表可根据自己需求自主编写,因为我用的生成器,所以所有表的实体都生成了,结构如下
5.编写用户登录接口及数据库映射文件,根据用户名查询出角色和权限列表,供后期shiro登录来用 UserMapper类,面向接口开发的Mybatis接口 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 package com.yang.dao; import com.yang.bean.User; import java.util.List; public interface UserMapper { int deleteByPrimaryKey(Long id); int insert(User record); User selectByPrimaryKey(Long id); List<User> selectAll(); int updateByPrimaryKey(User record); /** * 根据名称查询 * @param name * @return */ User selectByName(String name); /** * 登录接口 * @param user * @return */ User login(User user); }
UserMapper.xml,xml映射文件及sql编写文件,编写五表查询语句 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 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.yang.dao.UserMapper" > <resultMap id ="BaseResultMap" type ="com.yang.bean.User" > <id column ="id" property ="id" jdbcType ="BIGINT" /> <result column ="name" property ="name" jdbcType ="VARCHAR" /> <result column ="password" property ="password" jdbcType ="VARCHAR" /> <collection property ="roles" ofType ="com.yang.bean.Role" > <id column ="roleId" property ="id" jdbcType ="BIGINT" /> <result column ="roleName" property ="roleName" jdbcType ="VARCHAR" /> <collection property ="permissions" ofType ="com.yang.bean.Permission" > <id column ="pId" property ="id" jdbcType ="BIGINT" /> <result column ="permission" property ="permission" jdbcType ="VARCHAR" /> </collection > </collection > </resultMap > <delete id ="deleteByPrimaryKey" parameterType ="java.lang.Long" > delete from user where id = #{id,jdbcType=BIGINT} </delete > <insert id ="insert" parameterType ="com.yang.bean.User" > <selectKey resultType ="java.lang.Long" keyProperty ="id" order ="AFTER" > SELECT LAST_INSERT_ID() </selectKey > insert into user (`name`, `password`) values (#{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}) </insert > <update id ="updateByPrimaryKey" parameterType ="com.yang.bean.User" > update user set `name` = #{name,jdbcType=VARCHAR}, `password` = #{password,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} </update > <select id ="selectByPrimaryKey" resultMap ="BaseResultMap" parameterType ="java.lang.Long" > select id, `name`, `password` from user where id = #{id,jdbcType=BIGINT} </select > <select id ="selectAll" resultMap ="BaseResultMap" > select id, `name`, `password` from user </select > <select id ="selectByName" parameterType ="java.lang.String" resultMap ="BaseResultMap" > SELECT u.id id, u.`name`, u.`password`, r.id roleId, r.role_name roleName, p.id pId, p.permission FROM `user` AS u LEFT JOIN user_role AS ur on u.id=ur.user_id LEFT JOIN role r ON ur.role_id=r.id LEFT JOIN role_permission rp ON r.id= rp.role_id LEFT JOIN permission p ON rp.permission_id=p.id where u.`name` = #{name} </select > <select id ="login" parameterType ="com.yang.bean.User" resultMap ="BaseResultMap" > SELECT u.id id, u.`name`, u.`password`, r.id roleId, r.role_name roleName, p.id pId, p.permission FROM `user` AS u LEFT JOIN user_role AS ur on u.id=ur.user_id LEFT JOIN role r ON ur.role_id=r.id LEFT JOIN role_permission rp ON r.id= rp.role_id LEFT JOIN permission p ON rp.permission_id=p.id where u.`name` = #{name} and u.password=#{password} </select > </mapper >
6.此处编写了两个工具类,分别是:一个全局数据统一返回的类,一个用来定义常量的类,内容如下 1 2 3 4 5 6 7 8 9 10 package com.yang.util;public class Constant { public static String SUCCESS_RETUEN_CODE="0" ; public static String FAILURE_RETUEN_CODE="-9999" ; public static String HASE_RETUEN_CODE="1" ; }
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 package com.yang.bean;public class ResultObject <T > { private String code; private String msg; private T data; private Long count; public Long getCount () { return count; } public void setCount (Long count) { this .count = count; } public String getCode () { return code; } public void setCode (String code) { this .code = code; } public String getMsg () { return msg; } public void setMsg (String msg) { this .msg = msg; } public T getData () { return data; } public void setData (T data) { this .data = data; } }
7.开始配置shiro的自定义relam来做认证,MyShiroRealm,具体查询数据库的服务类,自己编写 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 package com.yang.shiro;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.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import com.yang.bean.Permission;import com.yang.bean.Role;import com.yang.bean.User;import com.yang.service.IUserService;public class MyShiroRealm extends AuthorizingRealm { @Autowired private IUserService userService; @Override protected AuthorizationInfo doGetAuthorizationInfo (PrincipalCollection principalCollection) { String name= (String) principalCollection.getPrimaryPrincipal(); User user = userService.getUserByName(name); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for (Role role:user.getRoles()) { simpleAuthorizationInfo.addRole(role.getRoleName()); for (Permission permission:role.getPermissions()) { simpleAuthorizationInfo.addStringPermission(permission.getPermission()); } } return simpleAuthorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken authenticationToken) { if (authenticationToken.getPrincipal() == null ) { return null ; } String name = authenticationToken.getPrincipal().toString(); User user = userService.getUserByName(name); if (user == null ) { return null ; } else { SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, user.getPassword().toString(), getName()); return simpleAuthenticationInfo; } } }
8.配置shiro的过滤器到spring的容器中,ShiroConfiguration 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 package com.yang.shiro;import java.util.HashMap;import java.util.Map;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.spring.LifecycleBeanPostProcessor;import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration public class ShiroConfiguration { @Bean public MyShiroRealm myShiroRealm () { MyShiroRealm myShiroRealm = new MyShiroRealm(); return myShiroRealm; } @Bean public SecurityManager securityManager () { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); return securityManager; } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean (SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String,String> map = new HashMap<String, String>(); map.put("/user/login" , "anon" ); map.put("/assets/**" , "anon" ); map.put("/404.html" ,"anon" ); map.put("/user/logout" ,"logout" ); map.put("/**" ,"authc" ); shiroFilterFactoryBean.setLoginUrl("/login.html" ); shiroFilterFactoryBean.setSuccessUrl("/index.html" ); shiroFilterFactoryBean.setUnauthorizedUrl("/error.html" ); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor (SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } @Bean public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor () { return new LifecycleBeanPostProcessor(); } @Bean public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator () { return new DefaultAdvisorAutoProxyCreator(); } }
9.由于shiro在登录认证时,如果用户验证失败,会有相关的异常抛出,编写全局异常处理器(ControllerAdvice),来处理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 47 48 49 50 51 52 53 54 package com.yang.excpetion;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.UnknownAccountException;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.RestController;import com.yang.bean.ResultObject;import com.yang.util.Constant;@RestController @ControllerAdvice public class MyExceptionHandler { @ExceptionHandler (UnknownAccountException.class) public ResultObject<Object> unknownAccountException () { ResultObject<Object> rs = new ResultObject<Object>(); rs.setCode(Constant.FAILURE_RETUEN_CODE); rs.setMsg("用户不存在" ); return rs; } @ExceptionHandler (IncorrectCredentialsException.class) public ResultObject<Object> incorrectCredentialsException () { ResultObject<Object> rs = new ResultObject<Object>(); rs.setCode(Constant.FAILURE_RETUEN_CODE); rs.setMsg("密码错误" ); return rs; } @ExceptionHandler (UnauthorizedException.class) public ResultObject<Object> nauthorizedException () { ResultObject<Object> rs = new ResultObject<Object>(); rs.setCode(Constant.FAILURE_RETUEN_CODE); rs.setMsg("当前用户没有权限" ); return rs; } }
10.编写登录,登出入口,并给查询所有用户的接口中加上角色要求 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 package com.yang.controller;import java.util.List;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authz.annotation.RequiresRoles;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.yang.bean.ResultObject;import com.yang.bean.User;import com.yang.service.IUserService;import com.yang.util.Constant;@RestController @RequestMapping ("/user" )public class UserController { @Autowired private IUserService userService; @RequestMapping ("/queryByName" ) public User getUserByName () { return userService.getUserByName("admin" ); } @RequestMapping (value = "/login" ) public ResultObject<User> login (User user) { ResultObject<User> rs = new ResultObject<User>(); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getName(),user.getPassword()); subject.login(usernamePasswordToken); rs.setCode(Constant.SUCCESS_RETUEN_CODE); rs.setMsg("成功登陆" ); user.setPassword("你想知道吗,我删了 哈哈" ); rs.setData(user); return rs; } @RequestMapping (value = "/logout" ) public ResultObject<String> user () { ResultObject<String> rs = new ResultObject<String>(); Subject subject = SecurityUtils.getSubject(); subject.logout(); rs.setCode(Constant.SUCCESS_RETUEN_CODE); rs.setMsg("成功退出" ); return rs; } @RequiresRoles ("admin" ) @RequestMapping ("/queryUserAll" ) public ResultObject<List<User>> queryUserAll() { ResultObject<List<User>> rs = new ResultObject<List<User>>(); rs.setCode(Constant.SUCCESS_RETUEN_CODE); List<User> list=userService.getAllUser(); rs.setData(list); rs.setCount(Long.valueOf(list.size())); return rs; } }
11.在public文件夹下编写登录界面和主界面,将登录界面和登录信息配置到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 <!DOCTYPE html> <html > <head > <meta charset ="UTF-8" > <title > Insert title here</title > </head > <body > <h2 > shiro测试登录</h2 > <form id ="form1" style ="line-height: 50px;" > 姓名:<input type ="text" id ="name" name ="name" /> <br /> 密码:<input type ="password" id ="pass" name ="password /" > <br /> <input type ="button" id ="login" value ="登陆一下下吧" /> </form > <script src ="assets/js/jquery-3.3.1.min.js" > </script > <script type ="text/javascript" > $("#login").on("click",login); function login(){ var data={ "name":$("#name").val(), "password":$("#pass").val() }; $.ajax({ //几个参数需要注意一下 type: "POST",//方法类型 dataType: "json",//预期服务器返回的数据类型 url: "/user/login" ,//url data: data, success: function (result) { if(result.code=="0"){ location.href="/index.html"; }else{ alert(result.msg); } }, error : function() { alert("登录失败"); } }); } </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html> <html > <head > <meta charset ="UTF-8" > <title > 主页</title > <script src ="assets/js/aJaxUtil.js" > </script > <script src ="assets/js/jquery-3.3.1.min.js" > </script > </head > <body > <h2 > 这里是主页</h2 > </body > <script type ="text/javascript" > </script > </html >
12.全部项目结构如下
13.在boot中启动项目,开始测试,启动文件如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.yang.boot;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ComponentScan;@SpringBootApplication @EnableAutoConfiguration @ComponentScan ("com.yang" ) @MapperScan ("com.yang.dao" ) public class StartShiroApplication { public static void main (String[] args) { SpringApplication.run(StartShiroApplication.class, args); } }
14.启动后,访问项目地址,自动跳转到login界面,输入其他界面地址,都会跳转到login界面,证明shiro拦截生效了
15.输入不存在的用户名,第二次输入错误的密码,返回信息如下
两个返回的信息证明,全局异常捕获拦截到了用户认证的两个异常,并且生效了
16.测试登录后的权限,由于在查询所有用户的权限上加上了必须为admin的角色
17.分别使用admin角色用户admin,devlop用户yang来登录测试queryUserAll接口(用户在sql脚本中插入并赋权的)
接口返回标识权限认证的保存信息已经被拦截掉,并且接口的权限认证已经生效
18.此时,shiro的认证和授权已经生效,整合完毕,源码点我获取 ,有问题欢迎来踩,附上常用注解 1 2 3 4 5 6 7 8 9 10 11 12 13 14 RequiresAuthentication: 使用该注解标注的类,实例,方法在访问或调用时,当前Subject必须在当前session中已经过认证。 RequiresGuest: 使用该注解标注的类,实例,方法在访问或调用时,当前Subject可以是“gust”身份,不需要经过认证或者在原先的session中存在记录。 RequiresPermissions: 当前Subject需要拥有某些特定的权限时,才能执行被该注解标注的方法。如果当前Subject不具有这样的权限,则方法不会被执行。 RequiresRoles: 当前Subject必须拥有所有指定的角色时,才能访问被该注解标注的方法。如果当天Subject不同时拥有所有指定角色,则方法不会执行还会抛出AuthorizationException异常。 RequiresUser 当前Subject必须是应用的用户,才能访问或调用被该注解标注的类,实例,方法。