GitHub源码地址:知了一笑
https://github.com/cicadasmile/middle-ware-parent

一、Shiro简介

1、基础概念

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。作为一款安全框架Shiro的设计相当巧妙。Shiro的应用不依赖任何容器,它不仅可以在JavaEE下使用,还可以应用在JavaSE环境中。

2、核心角色

1)Subject:认证主体

代表当前系统的使用者,就是用户,在Shiro的认证中,认证主体通常就是userName和passWord,或者其他用户相关的唯一标识。

2)SecurityManager:安全管理器

Shiro架构中最核心的组件,通过它可以协调其他组件完成用户认证和授权。实际上,SecurityManager就是Shiro框架的控制器。

3)Realm:域对象

定义了访问数据的方式,用来连接不同的数据源,如:关系数据库,配置文件等等。

3、核心理念

Shiro自己不维护用户和权限,通过Subject用户主体和Realm域对象的注入,完成用户的认证和授权。

二、整合SpringBoot2框架

1、核心依赖

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.4.0</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version>
</dependency>

2、Shiro核心配置

@Configuration
public class ShiroConfig {/*** Session Manager:会话管理* 即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;* 会话可以是普通JavaSE环境的,也可以是如Web环境的;*/@Bean("sessionManager")public SessionManager sessionManager(){DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();//设置session过期时间sessionManager.setGlobalSessionTimeout(60 * 60 * 1000);sessionManager.setSessionValidationSchedulerEnabled(true);// 去掉shiro登录时url里的JSESSIONIDsessionManager.setSessionIdUrlRewritingEnabled(false);return sessionManager;}/*** SecurityManager:安全管理器*/@Bean("securityManager")public SecurityManager securityManager(UserRealm userRealm, SessionManager sessionManager) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setSessionManager(sessionManager);securityManager.setRealm(userRealm);return securityManager;}/*** ShiroFilter是整个Shiro的入口点,用于拦截需要安全控制的请求进行处理*/@Bean("shiroFilter")public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();shiroFilter.setSecurityManager(securityManager);shiroFilter.setLoginUrl("/userLogin");shiroFilter.setUnauthorizedUrl("/");Map<String, String> filterMap = new LinkedHashMap<>();filterMap.put("/userLogin", "anon");shiroFilter.setFilterChainDefinitionMap(filterMap);return shiroFilter;}/*** 管理Shiro中一些bean的生命周期*/@Bean("lifecycleBeanPostProcessor")public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}/*** 扫描上下文,寻找所有的Advistor(通知器)* 将这些Advisor应用到所有符合切入点的Bean中。*/@Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();proxyCreator.setProxyTargetClass(true);return proxyCreator;}/*** 匹配所有加了 Shiro 认证注解的方法*/@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();advisor.setSecurityManager(securityManager);return advisor;}
}

3、域对象配置

@Component
public class UserRealm extends AuthorizingRealm {@Resourceprivate SysUserMapper sysUserMapper ;@Resourceprivate SysMenuMapper sysMenuMapper ;/*** 授权(验证权限时调用)* 获取用户权限集合*/@Overridepublic AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();if(user == null) {throw new UnknownAccountException("账号不存在");}List<String> permsList;//默认用户拥有最高权限List<SysMenuEntity> menuList = sysMenuMapper.selectList();permsList = new ArrayList<>(menuList.size());for(SysMenuEntity menu : menuList){permsList.add(menu.getPerms());}//用户权限列表Set<String> permsSet = new HashSet<>();for(String perms : permsList){if(StringUtils.isEmpty(perms)){continue;}permsSet.addAll(Arrays.asList(perms.trim().split(",")));}SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();info.setStringPermissions(permsSet);return info;}/*** 认证(登录时调用)* 验证用户登录*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken)authToken;//查询用户信息SysUserEntity user = sysUserMapper.selectOne(token.getUsername());//账号不存在if(user == null) {throw new UnknownAccountException("账号或密码不正确");}//账号锁定if(user.getStatus() == 0){throw new LockedAccountException("账号已被锁定,请联系管理员");}SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(),ByteSource.Util.bytes(user.getSalt()),getName());return info;}@Overridepublic void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);super.setCredentialsMatcher(shaCredentialsMatcher);}
}

4、核心工具类

public class ShiroUtils {/**  加密算法 */public final static String hashAlgorithmName = "SHA-256";/**  循环次数 */public final static int hashIterations = 16;public static String sha256(String password, String salt) {return new SimpleHash(hashAlgorithmName, password, salt, hashIterations).toString();}// 获取一个测试账号 adminpublic static void main(String[] args) {// 3743a4c09a17e6f2829febd09ca54e627810001cf255ddcae9dabd288a949c4aSystem.out.println(sha256("admin","123")) ;}/*** 获取会话*/public static Session getSession() {return SecurityUtils.getSubject().getSession();}/*** Subject:主体,代表了当前“用户”*/public static Subject getSubject() {return SecurityUtils.getSubject();}public static SysUserEntity getUserEntity() {return (SysUserEntity)SecurityUtils.getSubject().getPrincipal();}public static Long getUserId() {return getUserEntity().getUserId();}public static void setSessionAttribute(Object key, Object value) {getSession().setAttribute(key, value);}public static Object getSessionAttribute(Object key) {return getSession().getAttribute(key);}public static boolean isLogin() {return SecurityUtils.getSubject().getPrincipal() != null;}public static void logout() {SecurityUtils.getSubject().logout();}
}

5、自定义权限异常提示

@RestControllerAdvice
public class ShiroException {@ExceptionHandler(AuthorizationException.class)public String authorizationException (){return "抱歉您没有权限访问该内容!";}@ExceptionHandler(Exception.class)public String handleException(Exception e){return "系统异常!";}
}

三、案例演示代码

1、测试接口

@RestController
public class ShiroController {private static Logger LOGGER = LoggerFactory.getLogger(ShiroController.class) ;@Resourceprivate SysMenuMapper sysMenuMapper ;/*** 登录测试* http://localhost:7011/userLogin?userName=admin&passWord=admin*/@RequestMapping("/userLogin")public void userLogin (@RequestParam(value = "userName") String userName,@RequestParam(value = "passWord") String passWord){try{Subject subject = ShiroUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord);subject.login(token);LOGGER.info("登录成功");}catch (Exception e) {e.printStackTrace();}}/*** 服务器每次重启请求该接口之前必须先请求上面登录接口* http://localhost:7011/menu/list 获取所有菜单列表* 权限要求:sys:user:shiro*/@RequestMapping("/menu/list")@RequiresPermissions("sys:user:shiro")public List list(){return sysMenuMapper.selectList() ;}/*** 用户没有该权限,无法访问* 权限要求:ccc:ddd:bbb*/@RequestMapping("/menu/list2")@RequiresPermissions("ccc:ddd:bbb")public List list2(){return sysMenuMapper.selectList() ;}/*** 退出测试,退出后没有任何权限*/@RequestMapping("/userLogOut")public String logout (){ShiroUtils.logout();return "success" ;}
}

2、测试流程

1)、登录后取得权限
http://localhost:7011/userLogin?userName=admin&passWord=admin
2)、访问有权限接口
http://localhost:7011/menu/list
3)、访问无权限接口
http://localhost:7011/menu/list2
4)、退出登录
http://localhost:7011/userLogOut

四、源代码地址

GitHub地址:知了一笑
https://github.com/cicadasmile/middle-ware-parent
码云地址:知了一笑
https://gitee.com/cicadasmile/middle-ware-parent


SpringBoot2.0 整合 Shiro 框架,实现用户权限管理相关推荐

  1. SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题

    SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题 参考文章: (1)SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题 (2)https://www. ...

  2. SpringBoot2.0 整合 Dubbo框架 ,实现RPC服务远程调用

    一.Dubbo框架简介 1.框架依赖 图例说明: 1)图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层 ...

  3. SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理

    一.Security简介 1.基础概念 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配 ...

  4. SpringBoot2.0 整合 ElasticSearch框架,实现高性能搜索引擎

    本文源码 GitHub:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.安装和简介 ElasticSearch是一个基于Lucene的搜索 ...

  5. SpringBoot2.0 整合 QuartJob ,实现定时器实时管理

    一.QuartJob简介 1.一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大. 2.核心API (1).Scheduler 代表一个 Quartz 的独立运行容 ...

  6. SpringBoot2.0 整合 Swagger2 ,构建接口管理界面

    一.Swagger2简介 1.Swagger2优点 整合到Spring Boot中,构建强大RESTful API文档.省去接口文档管理工作,修改代码,自动更新,Swagger2也提供了强大的页面测试 ...

  7. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证)...

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证) ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框 ...

  8. SpringCloud、SpringBoot2.0 整合Oauth2 (四) 配置文件快速配置url过滤

    SpringBoot2.0 整合Oauth2 (四) 配置文件快速配置url过滤 文章目录 SpringBoot2.0 整合Oauth2 (四) 配置文件快速配置url过滤 1.添加url过滤配置 2 ...

  9. SpringBoot2.0 整合 Redis集群 ,实现消息队列场景

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent 一.Redis集群简介 1.RedisCluster概念 Re ...

最新文章

  1. html中连续点击某个标签会出现蓝色的解决方法
  2. 7秒钟的记忆?Facebook提出DL新算法,东南大学90后博士新作
  3. c# 通过API启动外部程序
  4. pg_dump 详解/使用举例
  5. JDK和cglib动态代理代码示例
  6. Linux系统网卡配置方法
  7. 面试官:为什么 Spring Boot 的 jar 可以直接运行
  8. 数据库日期时间显示在页面上格式错误的解决方案
  9. 阿里巴巴首席技术官程立:我们相信并正在践行的“好科技”
  10. 【转载】浅谈 看图软件 的设计与实现
  11. [转]Android限制只能在主线程中进行UI访问的实现原理
  12. (响应式PC端媒体查询)电脑屏幕分辨率尺寸大全
  13. mysql从字段取出地名_mysql中从字段中URL提取域名信息
  14. SQL常用替换字符串值的5种方法
  15. 苍井空老师推特唤醒中国网民正版意识
  16. 《上海悠悠接口自动化平台》-4.注册用例集实战演示
  17. oracle jdbc驱动jar包下载,oracle各个版本所需要的ojdbc jar驱动包以及版本对应关系...
  18. VMware Horizon 8安装部署(八)访问测试,成功部署。
  19. ICP经营许可证条件
  20. 我们都是被上帝咬过的苹果

热门文章

  1. 操作系统之计算机系统概述:6、系统调用
  2. VC++ CString互转double
  3. Python 抛异常处理(精)
  4. webServlet(/) 和 webServlet(/*) 的区别
  5. 为什么 c = tf.matmul(a, b) 不立即执行矩阵乘法?
  6. python+selenium+unittest测试框架1-unittest单元测试框架和断言
  7. Win7如何关闭 打开文件-安全警告
  8. Let's Encrypt(开源SSL证书管理工具)
  9. 自己动手写spring(三) 支持注解方式
  10. ajax访问遇到Session失效问题