Hello大家好,本章我们添加shiro权限保护接口功能 。有问题可以联系我mr_beany@163.com。另求各路大神指点,感谢
Shiro是一个Java平台的开源权限框架,用于认证和访问授权。具体来说,满足对如下元素的支持:
简单来说shiro是通过自己的配置,来保证接口只能被指定的角色或权限访问,保证了接口的安全。
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.4.0-RC2</version> </dependency>
1:修改原有 userInfo
表
添加 password(用户密码,经过加密之后的),salt(加密盐值)
修改之后结构为下图
其中 password
数据为123456加密之后生成的
2:添加角色表
CREATE TABLE `sys_role` ( `id` varchar(36) NOT NULL COMMENT '角色名称', `role_name` varchar(255) DEFAULT NULL COMMENT '角色名称,用于显示', `role_desc` varchar(255) DEFAULT NULL COMMENT '角色描述', `role_value` varchar(255) DEFAULT NULL COMMENT '角色值,用于权限判断', `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `is_disable` int(1) DEFAULT NULL COMMENT '是否禁用', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色表';
3:添加用户角色关系表
CREATE TABLE `user_role` ( `id` varchar(36) NOT NULL, `user_id` varchar(36) DEFAULT NULL COMMENT '用户ID', `role_id` varchar(36) DEFAULT NULL COMMENT '角色id', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户角色关系表';
4:添加权限表
CREATE TABLE `sys_perm` ( `id` varchar(36) NOT NULL, `perm_name` varchar(255) DEFAULT NULL COMMENT '权限名称', `perm_desc` varchar(255) DEFAULT NULL COMMENT '权限描述', `perm_value` varchar(255) DEFAULT NULL COMMENT '权限值', `create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, `is_disable` int(1) DEFAULT NULL COMMENT '是否禁用', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
5:添加角色权限表
CREATE TABLE `role_perm` ( `id` varchar(36) NOT NULL, `perm_id` varchar(32) DEFAULT NULL COMMENT '权限id', `role_id` varchar(32) DEFAULT NULL COMMENT '角色id', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色权限表';
表关系大致为下图,一个用户对应多个角色,一个角色对用多个权限
原谅我辣鸡的画图
大家直接生成就可以,由于代码过多,这里不做展示,详情可以去码云上参考
UserRoleMapper.xml
<!--根据用户id查询该用户所有角色--> <select id="getRolesByUserId" resultType="string" parameterType="string"> select sr.role_value from user_role ur left join sys_role sr on ur.role_id = sr.id where ur.user_id = #{userId,jdbcType=VARCHAR} and sr.is_disable = 0 </select>
UserRoleMapper.java
List<String> getRolesByUserId(String userId);
RolePermMapper.xml
<select id="getPermsByUserId" resultType="string" parameterType="string"> select distinct p.perm_value from sys_perm p, role_perm rp, user_role ur where p.id = rp.perm_id and ur.role_id = rp.role_id and ur.user_id = #{userId,jdbcType=VARCHAR} and p.is_disable = 0 </select>
说明,这里查询出该用户对应的所有权限,由于角色与权限是多对多的关系,所以查询出的用户的权限可能会有重复,需要 distinct
去重。
RolePermMapper.java
List<String> getPermsByUserId(String userId);
修改userInfo实体类为如下
package com.example.demo.model; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Transient; import java.util.HashSet; import java.util.Set; /** * @author 张瑶 * @Description: * @time 2018/4/18 11:55 */ public class UserInfo { /** * 主键 */ @Id private String id; /** * 用户名 */ @Column(name = "user_name") private String userName; private String password; /** * 加密盐值 */ private String salt; /** * 用户所有角色值,用于shiro做角色权限的判断 */ @Transient private Set<String> roles; /** * 用户所有权限值,用于shiro做资源权限的判断 */ @Transient private Set<String> perms; public String getId() { return id; } public void setId(String id) { this.id = id; } 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 Set<String> getRoles() { return roles; } public void setRoles(Set<String> roles) { this.roles = roles; } public Set<String> getPerms() { return perms; } public void setPerms(Set<String> perms) { this.perms = perms; } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } }
创建core→shiro→CustomRealm.java
1:登录认证实现
在Shiro中,最终是通过Realm来获取应用程序中的用户、角色及权限信息的。通常情况下,在Realm中会直接从我们的数据源中获取Shiro需要的验证信息。可以说,Realm是专用于安全框架的DAO.
Shiro的认证过程最终会交由Realm执行,这时会调用Realm的 getAuthenticationInfo(token)
方法。
该方法主要执行以下操作:
AuthenticationInfo AuthenticationException
而在我们的应用程序中要做的就是自定义一个Realm类,继承AuthorizingRealm抽象类,重载doGetAuthenticationInfo(),重写获取用户信息的方法。
2:链接权限的实现
重载doGetAuthorizationInfo(),来定义如何获取用户的角色和权限的逻辑,给shiro做权限判断
完整代码如下
package com.example.demo.core.shiro; import com.example.demo.model.UserInfo; import com.example.demo.service.RolePermService; import com.example.demo.service.UserInfoService; import com.example.demo.service.UserRoleService; import org.apache.shiro.authc.*; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.authz.AuthorizationException; 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.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashSet; import java.util.List; import java.util.Set; /** * 自定义如何查询用户信息,如何查询用户的角色和权限,如何校验密码等逻辑 */ public class CustomRealm extends AuthorizingRealm { @Autowired private UserInfoService userService; @Autowired private UserRoleService userRoleService; @Autowired private RolePermService rolePermService; /** * 告诉shiro如何根据获取到的用户信息中的密码和盐值来校验密码 */ { //设置用于匹配密码的CredentialsMatcher HashedCredentialsMatcher hashMatcher = new HashedCredentialsMatcher(); hashMatcher.setHashAlgorithmName("md5"); hashMatcher.setStoredCredentialsHexEncoded(true); //加密的次数 hashMatcher.setHashIterations(1024); this.setCredentialsMatcher(hashMatcher); } /** * 定义如何获取用户的角色和权限的逻辑,给shiro做权限判断 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { if (principals == null) { throw new AuthorizationException("PrincipalCollection method argument cannot be null."); } UserInfo user = (UserInfo) getAvailablePrincipal(principals); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setRoles(user.getRoles()); info.setStringPermissions(user.getPerms()); return info; } /** * 定义如何获取用户信息的业务逻辑,给shiro做登录 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; String username = upToken.getUsername(); if (username == null) { throw new AccountException("Null usernames are not allowed by this realm."); } UserInfo userDB = userService.selectBy("userName",username); if (userDB == null) { throw new UnknownAccountException("No account found for admin [" + username + "]"); } //查询用户的角色和权限存到SimpleAuthenticationInfo中,这样在其它地方 //SecurityUtils.getSubject().getPrincipal()就能拿出用户的所有信息,包括角色和权限 List<String> roleList = userRoleService.getRolesByUserId(userDB.getId()); List<String> permList = rolePermService.getPermsByUserId(userDB.getId()); Set<String> roles = new HashSet(roleList); Set<String> perms = new HashSet(permList); userDB.setRoles(roles); userDB.setPerms(perms); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userDB, userDB.getPassword(), getName()); info.setCredentialsSalt(ByteSource.Util.bytes(userDB.getSalt())); return info; } }
创建core→configurer→ShiroConfigurer
package com.example.demo.core.configurer; import com.example.demo.core.shiro.CustomRealm; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; @Configuration public class ShiroConfigurer { /** * 注入自定义的realm,告诉shiro如何获取用户信息来做登录或权限控制 */ @Bean public Realm realm() { return new CustomRealm(); } @Bean public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); /** * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。 * 在@Controller注解的类的方法中加入@RequiresRole注解,会导致该方法无法映射请求,导致返回404。 * 加入这项配置能解决这个bug */ creator.setUsePrefix(true); return creator; } /** * 这里统一做鉴权,即判断哪些请求路径需要用户登录,哪些请求路径不需要用户登录 * @return */ @Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition(); chain.addPathDefinition( "/userInfo/selectById", "authc, roles[admin]"); chain.addPathDefinition( "/logout", "anon"); chain.addPathDefinition( "/userInfo/selectAll", "anon"); chain.addPathDefinition( "/userInfo/login", "anon"); chain.addPathDefinition( "/**", "authc"); return chain; } }
shiro提供和多个默认的过滤器,我们可以用这些过滤器来配置控制指定url的权限:
配置缩写 | 对应的过滤器 | 功能 |
---|---|---|
anon | AnonymousFilter | 指定url可以匿名访问 |
authc | FormAuthenticationFilter | 指定url需要form表单登录,默认会从请求中获取 username 、 password , rememberMe 等参数并尝试登录,如果登录不了就会跳转到loginUrl配置的路径。我们也可以用这个过滤器做默认的登录逻辑,但是一般都是我们自己在控制器写登录逻辑的,自己写的话出错返回的信息都可以定制。 |
authcBasic | BasicHttpAuthenticationFilter | 指定url需要basic登录 |
logout | LogoutFilter | 登出过滤器,配置指定url就可以实现退出功能,非常方便 |
noSessionCreation | NoSessionCreationFilter | 禁止创建会话 |
perms | PermissionsAuthorizationFilter | 需要指定权限才能访问 |
port | PortFilter | 需要指定端口才能访问 |
rest | HttpMethodPermissionFilter | 将http请求方法转化成相应的动词来构造一个权限字符串 |
roles | RolesAuthorizationFilter | 需要指定角色才能访问 |
ssl | SslFilter | 需要https请求才能访问 |
user | UserFilter | 需要已登录或“记住我”的用户才能访问 |
@PostMapping("/login") public RetResult<UserInfo> login(String userName, String password) { Subject currentUser = SecurityUtils.getSubject(); //登录 try { currentUser.login(new UsernamePasswordToken(userName, password)); }catch (IncorrectCredentialsException i){ throw new ServiceException("密码输入错误"); } //从session取出用户信息 UserInfo user = (UserInfo) currentUser.getPrincipal(); return RetResponse.makeOKRsp(user); }
INSERT INTO `sys_role` VALUES ('1', '财务', '负责发工资', 'cw', '2018-05-26 00:37:52', null, '0'); INSERT INTO `sys_role` VALUES ('2', '人事', '负责员工', 'rs', '2018-05-26 00:38:18', null, '0'); INSERT INTO `user_role` VALUES ('1', '1', '1'); INSERT INTO `user_role` VALUES ('2', '1', '2'); INSERT INTO `sys_perm` VALUES ('1', '创建', '创建权限', 'create', '2018-05-26 00:39:16', null, '0'); INSERT INTO `sys_perm` VALUES ('2', '删除', '删除权限', 'delete', '2018-05-26 00:39:39', null, '0'); INSERT INTO `sys_perm` VALUES ('3', '修改', '修改权限', 'update', '2018-05-26 00:39:58', null, '0'); INSERT INTO `sys_perm` VALUES ('4', '查询', '查询权限', 'select', '2018-05-26 00:40:16', null, '0'); INSERT INTO `role_perm` VALUES ('1', '1', '1'); INSERT INTO `role_perm` VALUES ('2', '2', '1'); INSERT INTO `role_perm` VALUES ('3', '1', '2'); INSERT INTO `role_perm` VALUES ('4', '2', '2'); INSERT INTO `role_perm` VALUES ('5', '3', '2'); INSERT INTO `role_perm` VALUES ('6', '4', '2');
package com.example.demo.controller; import com.example.demo.core.ret.ServiceException; import com.example.demo.model.UserInfo; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.UnauthenticatedException; import org.apache.shiro.authz.UnauthorizedException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("shiroUtils") public class ShiroUtilsController { @GetMapping("/noLogin") public void noLogin() { throw new UnauthenticatedException(); } @GetMapping("/noAuthorize") public void noAuthorize() { throw new UnauthorizedException(); } @PostMapping("/getNowUser") public UserInfo getNowUser() { UserInfo u = (UserInfo) SecurityUtils.getSubject().getPrincipal(); return u; } }
package com.example.demo.core.ret; /** * @Description: 响应码枚举,参考HTTP状态码的语义 * @author 张瑶 * @date 2018/4/19 09:42 */ public enum RetCode { // 成功 SUCCESS(200), // 失败 FAIL(400), // 未认证(签名错误) UNAUTHORIZED(401), /** 未登录 */ UNAUTHEN(4401), /** 未授权,拒绝访问 */ UNAUTHZ(4403), // 服务器内部错误 INTERNAL_SERVER_ERROR(500); public int code; RetCode(int code) { this.code = code; } }
@Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { exceptionResolvers.add(new HandlerExceptionResolver() { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { RetResult<Object> result = new RetResult<Object>(); // 业务失败的异常,如“账号或密码错误” if (e instanceof ServiceException) { result.setCode(RetCode.FAIL).setMsg(e.getMessage()).setData(null); LOGGER.info(e.getMessage()); } else if (e instanceof NoHandlerFoundException) { result.setCode(RetCode.NOT_FOUND).setMsg("接口 [" + request.getRequestURI() + "] 不存在"); } else if (e instanceof UnauthorizedException) { result.setCode(RetCode.UNAUTHEN).setMsg("用户没有访问权限").setData(null); }else if (e instanceof UnauthenticatedException) { result.setCode(RetCode.UNAUTHEN).setMsg("用户未登录").setData(null); }else if (e instanceof ServletException) { result.setCode(RetCode.FAIL).setMsg(e.getMessage()); } else { result.setCode(RetCode.INTERNAL_SERVER_ERROR).setMsg("接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员"); String message; if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s", request.getRequestURI(), handlerMethod.getBean().getClass().getName(), handlerMethod.getMethod() .getName(), e.getMessage()); } else { message = e.getMessage(); } LOGGER.error(message, e); } responseResult(response, result); return new ModelAndView(); } }); }
在 application.properties
中添加
#shiro配置 #用户未登录 shiro.loginUrl=/shiroUtils/noLogin #用户没有权限 shiro.unauthorizedUrl=/shiroUtils/noAuthorize
输入localhost:8080/userInfo/selectAll
我们可以看到可以拿到数据
输入localhost:8080/userInfo/selectById
然后登陆
再次访问localhost:8080/userInfo/selectById,我们可以看到shiro已经生效
修改用户访问权限,重新启动,重新登陆
chain.addPathDefinition( "/userInfo/selectById", "authc, roles[cw]");
再次访问localhost:8080/userInfo/selectById
优化一 :权限不可能一直不变,当我们需要修改权限时,我们需要手动修改shiro配置文件,显然是不合理的,最好的办法是把权限存储在数据库中,修改时修改数据库
1:创建url资源表并添加数据
CREATE TABLE `sys_permission_init` ( `id` varchar(255) NOT NULL, `url` varchar(255) DEFAULT NULL COMMENT '程序对应url地址', `permission_init` varchar(255) DEFAULT NULL COMMENT '对应shiro权限', `sort` int(100) DEFAULT NULL COMMENT '排序', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `sys_permission_init` VALUES ('1', '/userInfo/login', 'anon', '1'); INSERT INTO `sys_permission_init` VALUES ('2', '/userInfo/selectAll', 'anon', '2'); INSERT INTO `sys_permission_init` VALUES ('3', '/logout', 'anon', '3'); INSERT INTO `sys_permission_init` VALUES ('4', '/**', 'authc', '0'); INSERT INTO `sys_permission_init` VALUES ('5', '/userInfo/selectAlla', 'authc, roles[admin]', '6'); INSERT INTO `sys_permission_init` VALUES ('6', '/sysPermissionInit/aaa', 'anon', '5');
这里我们需要让 '/**'
始终在最后,所以需要添加 sort
进行排序
2:根据工具生成mapper,dao,service,controller并添加我们需要的查询方法
SysPermissionInitMapper.xml
<sql id="Base_Column_List"> id, url, permission_init, sort </sql> <select id="selectAllOrderBySort" resultMap="BaseResultMap"> SELECT <include refid="Base_Column_List"/> from sys_permission_init order by sort desc </select>
SysPermissionInitMapper.java
List<SysPermissionInit> selectAllOrderBySort();
3:修改 ShiroConfigurer.java
修改后如下
package com.example.demo.core.configurer; import com.example.demo.core.shiro.CustomRealm; import com.example.demo.model.SysPermissionInit; import com.example.demo.service.SysPermissionInitService; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition; import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; import java.util.List; @Configuration public class ShiroConfigurer { @Resource private SysPermissionInitService sysPermissionInitService; /** * 注入自定义的realm,告诉shiro如何获取用户信息来做登录或权限控制 */ @Bean public Realm realm() { return new CustomRealm(); } @Bean public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); /** * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。 * 在@Controller注解的类的方法中加入@RequiresRole注解,会导致该方法无法映射请求,导致返回404。 * 加入这项配置能解决这个bug */ creator.setUsePrefix(true); return creator; } /** * 这里统一做鉴权,即判断哪些请求路径需要用户登录,哪些请求路径不需要用户登录 * @return */ @Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition(); List<SysPermissionInit> list = sysPermissionInitService.selectAllOrderBySort(); for(int i = 0,length = list.size();i<length;i++){ SysPermissionInit sysPermissionInit = list.get(i); chain.addPathDefinition(sysPermissionInit.getUrl(), sysPermissionInit.getPermissionInit()); } return chain; } }
4:测试
输入localhost:8080/userInfo/selectById
然后登陆
再次访问localhost:8080/userInfo/selectById,我们可以看到shiro已经生效
修改数据库用户访问权限,重新启动,重新登陆
UPDATE sys_permission_init SET permission_init = 'authc, roles[cw]' WHERE id = 5
再次访问localhost:8080/userInfo/selectById
优化二 :每次当我们修改权限信息时,都需要重启服务器,这显然也是不合理的
1:创建shiroService
package com.example.demo.service; import java.util.Map; /** * shiro 动态更新权限 */ public interface ShiroService { Map<String, String> loadFilterChainDefinitions(); /** * 动态修改权限 */ void updatePermission(); }
2:创建shiroServiceImpl
package com.example.demo.service.impl; import com.example.demo.model.SysPermissionInit; import com.example.demo.service.ShiroService; import com.example.demo.service.SysPermissionInitService; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager; import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver; import org.apache.shiro.web.servlet.AbstractShiroFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.List; import java.util.Map; @Service public class ShiroServiceImpl implements ShiroService { @Autowired ShiroFilterFactoryBean shiroFilterFactoryBean; @Autowired SysPermissionInitService sysPermissionInitService; /** * 初始化权限 */ @Override public Map<String, String> loadFilterChainDefinitions() { // 权限控制map.从数据库获取 Map<String, String> filterChainDefinitionMap = new HashMap<>(); List<SysPermissionInit> list = sysPermissionInitService.selectAllOrderBySort(); for (SysPermissionInit sysPermissionInit : list) { filterChainDefinitionMap.put(sysPermissionInit.getUrl(), sysPermissionInit.getPermissionInit()); } return filterChainDefinitionMap; } /** * 重新加载权限 */ @Override public void updatePermission() { synchronized (shiroFilterFactoryBean) { AbstractShiroFilter shiroFilter = null; try { shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean .getObject(); } catch (Exception e) { throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!"); } PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter .getFilterChainResolver(); DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver .getFilterChainManager(); // 清空老的权限控制 manager.getFilterChains().clear(); shiroFilterFactoryBean.getFilterChainDefinitionMap().clear(); shiroFilterFactoryBean.setFilterChainDefinitionMap(loadFilterChainDefinitions()); // 重新构建生成 Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap(); for (Map.Entry<String, String> entry : chains.entrySet()) { String url = entry.getKey(); String chainDefinition = entry.getValue().trim().replace(" ", ""); manager.createChain(url, chainDefinition); } System.out.println("更新权限成功!!"); } } }
3:修改shiroUtilsController
添加如下代码
/** * @Description: 重新加载shiro权限 * @throws Exception */ @PostMapping("/updatePermission") public void updatePermission() throws Exception { shiroService.updatePermission(); }
4:测试
输入localhost:8080/userInfo/selectById
修改权限
UPDATE sys_permission_init SET permission_init = 'authc, roles[cw1]' WHERE id = 5
输入localhost:8080/shiroUtils/updatePermission 重新加载权限
注意:此刻我们并没有修改程序任何一个地方,也没有重启服务器
输入localhost:8080/userInfo/selectById
成功!
gitee.com/beany/mySpr…
写文章不易,如对您有帮助,请帮忙点下star
添加shiro权限保护接口功能已完成,后续功能接下来陆续更新,有问题可以联系我mr_beany@163.com。另求各路大神指点,感谢大家。