之前项目鉴权一直使用的Shiro,那是在Spring MVC里面使用的比较多,而且都是用XML来配置,用Shiro来做权限控制相对比较简单而且成熟,而且我一直都把Shiro的session放在mongodb中,这个比较符合mongodb的设计初衷,而且在分布式项目中mongodb也作为一个中间层,用来很好很方便解决分布式环境下的session同步的问题。

 自从SpringBoot问世之后我的项目基本上能用SpringBoot的就会用SpringBoot,用MAVEN做统一集中管理也很方便,虽然SpringBoot也提供了一套权限安全框架Spring Security,但是相对来说还是不是太好用,所以还是用Shiro来的方便一点,SpringBoot集成Shiro要比Spring MVC要简单的多,至少没有一堆XML配置,看起来更清爽,那么接下来我们就开始集成。

 第一步必然是在MAVEN中先添加Shiro和mongo的依赖,我用的Shiro版本是

  1. <shiro.version>1.2.3</shiro.version>

添加依赖:

  1. <dependency>
  2. <groupId>org.apache.shiro</groupId>
  3. <artifactId>shiro-core</artifactId>
  4. <version>${shiro.version}</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.shiro</groupId>
  8. <artifactId>shiro-web</artifactId>
  9. <version>${shiro.version}</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.shiro</groupId>
  13. <artifactId>shiro-spring</artifactId>
  14. <version>${shiro.version}</version>
  15. </dependency>
  16.  
  17. <dependency>
  18. <groupId>org.mongodb</groupId>
  19. <artifactId>mongo-java-driver</artifactId>
  20. <version>3.0.0</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.springframework.data</groupId>
  24. <artifactId>spring-data-mongodb</artifactId>
  25. <version>1.7.0.RELEASE</version>
  26. </dependency>

然后在application.xml或yml中配置mongodb

  1. spring.data.mongodb.host=127.0.0.1
  2. spring.data.mongodb.port=27017
  3. spring.data.mongodb.database=SHIRO_INFO

配置完成之后我们开始正式写Shiro认证的代码,先自定义一个鉴权realm,继承自AuthorizingRealm

  1. public class ShiroDbRealm extends AuthorizingRealm {
  2.  
  3. /**
  4. * 用户信息操作
  5. */
  6. private SystemUserService systemUserService;
  7.  
  8. public ShiroDbRealm() {}
  9.  
  10. public ShiroDbRealm(SystemUserService systemUserService) {
  11. this.systemUserService = systemUserService;
  12. }
  13.  
  14. /**
  15. * 授权信息
  16. */
  17. @Override
  18. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  19. SimpleAuthorizationInfo info = (SimpleAuthorizationInfo) ShiroKit.getShiroSessionAttr("perms");
  20. if (null != info && !CollectionUtils.isEmpty(info.getRoles())
  21. && !CollectionUtils.isEmpty(info.getStringPermissions())) {
  22. return info;
  23.  
  24. }
  25. return null;
  26.  
  27. }
  28.  
  29. /**
  30. * 认证信息
  31. */
  32. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
  33. throws AuthenticationException {
  34. UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
  35. String userName = token.getUsername();
  36. if (userName != null && !"".equals(userName)) {
  37. SystemUser key = new SystemUser();
  38. key.setLoginName(token.getUsername());
  39. key.setPassword(String.valueOf(token.getPassword()));
  40. SystemUser user = systemUserService.login(key);
  41.  
  42. if (user != null) {
  43. Subject userTemp = SecurityUtils.getSubject();
  44. userTemp.getSession().setAttribute("userId", user.getId());
  45. userTemp.getSession().setAttribute("userName", user.getUserName());
  46. return new SimpleAuthenticationInfo(user.getLoginName(), user.getPassword(), getName());
  47. }
  48. }
  49. return null;
  50. }
  51.  
  52. }

存储session进mongodb的Repository和实现:

  1. public interface ShiroSessionRepository {
  2.  
  3. /**
  4. *
  5. * @param session
  6. */
  7. void saveSession(Session session);
  8. ......
  9. }

MongoDBSessionRepository.java

  1. public class MongoDBSessionRepository implements ShiroSessionRepository {
  2. private MongoTemplate mongoTemplate;
  3.  
  4. public MongoDBSessionRepository() {}
  5.  
  6. public MongoDBSessionRepository(MongoTemplate mongoTemplate) {
  7. this.mongoTemplate = mongoTemplate;
  8. }
  9. @Override
  10. public void saveSession(Session session) {
  11. if (session == null || session.getId() == null) {
  12. return;
  13. }
  14. SessionBean bean = new SessionBean();
  15. bean.setKey(getSessionKey(session.getId()));
  16. bean.setValue(SerializeUtil.serialize(session));
  17. bean.setPrincipal(null);
  18. bean.setHost(session.getHost());
  19. bean.setStartTimestamp(session.getStartTimestamp());
  20. bean.setLastAccessTime(session.getLastAccessTime());
  21. bean.setTimeoutTime(getTimeoutTime(session.getStartTimestamp(), session.getTimeout()));
  22. mongoTemplate.insert(bean);
  23. }
  24. ......
  25. }

ShiroSessionDAO.java

  1. public class ShiroSessionDAO extends AbstractSessionDAO {
  2.  
  3. /**
  4. * 日志记录器
  5. */
  6. private static final Logger log = LoggerFactory.getLogger(ShiroSessionDAO.class);
  7.  
  8. /**
  9. * 数据库存储
  10. */
  11. private ShiroSessionRepository shiroSessionRepository;
  12.  
  13. /**
  14. *
  15. * @return
  16. */
  17. public ShiroSessionRepository getShiroSessionRepository() {
  18. return shiroSessionRepository;
  19. }
  20.  
  21. /**
  22. *
  23. * @param shiroSessionRepository
  24. */
  25. public void setShiroSessionRepository(ShiroSessionRepository shiroSessionRepository) {
  26. this.shiroSessionRepository = shiroSessionRepository;
  27. }
  28.  
  29. @Override
  30. public void update(Session session) throws UnknownSessionException {
  31. getShiroSessionRepository().updateSession(session);
  32. }
  33.  
  34. @Override
  35. public void delete(Session session) {
  36. if (session == null) {
  37. log.error("session can not be null,delete failed");
  38. return;
  39. }
  40. Serializable id = session.getId();
  41. if (id != null) {
  42. getShiroSessionRepository().deleteSession(id);
  43. }
  44. }
  45.  
  46. @Override
  47. public Collection<Session> getActiveSessions() {
  48. return getShiroSessionRepository().getAllSessions();
  49. }
  50.  
  51. @Override
  52. protected Serializable doCreate(Session session) {
  53. Serializable sessionId = this.generateSessionId(session);
  54. this.assignSessionId(session, sessionId);
  55. getShiroSessionRepository().saveSession(session);
  56. return sessionId;
  57. }
  58.  
  59. @Override
  60. protected Session doReadSession(Serializable sessionId) {
  61. return getShiroSessionRepository().getSession(sessionId);
  62. }
  63.  
  64. }

OK!所有基础类已经完成,最后写一个config用来全部初始化和配置Shiro

  1. @Configuration
  2. public class ShiroConfig {
  3. @Resource
  4. private MongoTemplate mongoTemplate;
  5. @Resource
  6. private SystemUserService systemUserService;// 这是用来判断用户名和密码的service
  7.  
  8. @Bean
  9. public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
  10. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  11.  
  12. shiroFilterFactoryBean.setSecurityManager(securityManager);
  13. shiroFilterFactoryBean.setLoginUrl("/login");
  14. shiroFilterFactoryBean.setSuccessUrl("/index");
  15. shiroFilterFactoryBean.setUnauthorizedUrl("/403");
  16.  
  17. // 拦截器.
  18. Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
  19. filterChainDefinitionMap.put("/static/**", "anon");
  20. filterChainDefinitionMap.put("/ajaxLogin", "anon");
  21. filterChainDefinitionMap.put("/libs/**", "anon");
  22. filterChainDefinitionMap.put("/images/**", "anon");
  23. filterChainDefinitionMap.put("/logout", "logout");
  24. filterChainDefinitionMap.put("/**", "authc");
  25.  
  26. shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
  27. return shiroFilterFactoryBean;
  28. }
  29.  
  30. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
  31. DefaultWebSecurityManager securityManager) {
  32. AuthorizationAttributeSourceAdvisor adv = new AuthorizationAttributeSourceAdvisor();
  33. adv.setSecurityManager(securityManager);
  34. return adv;
  35. }
  36.  
  37. @Bean
  38. public DefaultWebSecurityManager securityManager(DefaultWebSessionManager sessionManager,
  39. ShiroDbRealm myShiroRealm) {
  40. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  41. // 设置realm.
  42. securityManager.setRealm(myShiroRealm);
  43. securityManager.setSessionManager(sessionManager);
  44. return securityManager;
  45. }
  46.  
  47. /**
  48. * 身份认证realm; (这里传递systemUserService给自定义的ShiroDbRealm初始化)
  49. *
  50. * @return
  51. */
  52. @Bean
  53. public ShiroDbRealm myShiroRealm() {
  54. ShiroDbRealm myShiroRealm = new ShiroDbRealm(systemUserService);
  55. return myShiroRealm;
  56. }
  57.  
  58. @Bean
  59. public DefaultWebSessionManager sessionManager(ShiroSessionDAO shiroSessionDao) {
  60. DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
  61. sessionManager.setGlobalSessionTimeout(1800000l);
  62. sessionManager.setDeleteInvalidSessions(true);
  63. sessionManager.setSessionValidationSchedulerEnabled(true);
  64. sessionManager.setSessionDAO(shiroSessionDao);
  65. sessionManager.setSessionIdCookieEnabled(true);
  66. SimpleCookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
  67. cookie.setHttpOnly(true);
  68. cookie.setMaxAge(1800000);
  69. sessionManager.setSessionIdCookie(cookie);
  70. return sessionManager;
  71. }
  72.  
  73. @Bean
  74. public ShiroSessionDAO shiroSessionDao(MongoDBSessionRepository shiroSessionRepository) {
  75. ShiroSessionDAO dao = new ShiroSessionDAO();
  76. dao.setShiroSessionRepository(shiroSessionRepository);
  77. return dao;
  78. }
  79.  
  80. @Bean
  81. MongoDBSessionRepository shiroSessionRepository() {
  82. MongoDBSessionRepository resp = new MongoDBSessionRepository(mongoTemplate);
  83. return resp;
  84. }
  85.  
  86. }

好了,大功告成,这里只是一个简单的配置,代码也是我从项目里面节选和修改过的,至于在controller里面怎么使用,怎么做不同权限的鉴权工作那就在自己的代码里面实现就行。

文章来源:

dhttp://www.tianshangkun.com/2017/11/10/SpringBoot%E9%9B%86%E6%88%90Shiro%E5%B9%B6%E7%94%A8MongoDB%E5%81%9ASession%E5%AD%98%E5%82%A8/

更多参考内容:http://www.roncoo.com/article/index?tn=SpringBoot

SpringBoot集成Shiro并用MongoDB做Session存储的更多相关文章

  1. SpringBoot集成Shiro 实现动态加载权限

    一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...

  2. SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架

    SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...

  3. springboot集成shiro实现权限认证

    github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...

  4. springboot集成shiro 实现权限控制(转)

    shiro apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自 ...

  5. 【Shiro】SpringBoot集成Shiro

    项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...

  6. SpringBoot集成Shiro安全框架

    跟着我的步骤:先运行起来再说 Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc 一:导包 <!-- Shiro安全框架 ...

  7. springboot集成redis使用redis作为session报错ClassNotFoundException类RememberMeServices

    springboot 集成redis使用redis作为缓存,会报错的问题. 错误信息: java.lang.IllegalStateException: Error processing condit ...

  8. SpringBoot集成Shiro实现权限控制

    Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...

  9. springboot 集成shiro

    首先看下shiro configuration 的配置,重要部分用红色标出了 package cn.xiaojf.today.shiro.configuration; import at.pollux ...

随机推荐

  1. 小甲鱼OD学习第12讲

    这次我们的任务是破解这个需要特定的注册码的软件,如下图 我们从字符串入手,输入register,搜索 我们点击    查找下一个,看看有什么有用的字符串,如下图 然后,在下方,我们发现了  Regis ...

  2. 损失函数 hinge loss vs softmax loss

    1. 损失函数 损失函数(Loss function)是用来估量你模型的预测值 f(x) 与真实值 Y 的不一致程度,它是一个非负实值函数,通常用 L(Y,f(x)) 来表示. 损失函数越小,模型的鲁 ...

  3. 单用户模式与救援模式:linux学习第三篇

    单用户模式 1.      重新启动,在下列界面选项第一项按 e 按e后进入此grub界面(启动工具) 2.      找到linux16所在行,将'ro'(只读)修改为'rw'(读写),并加上 in ...

  4. selenium2 python自动化测试实战(回归测试)

    selenium2 python自动化测试实战 最近接手商城的项目,针对后台测试,功能比较简单,但是流程比较繁多,涉及到前后台的交叉测试.在对整个项目进行第一轮测试完成之后,考虑以后回归测试任务比较重 ...

  5. checkbox/input文本框与文字对齐

    3种方法都能实现checkbox文本框或radio文本框与文字对齐: <meta charset="utf-8"> <input style="vert ...

  6. easyui datagrid 右边框被隐藏

    问题前: 如下图: 解决思路: 待文档加载完成后再执行dategrid函数 $(function () { $("#tt").datagrid({ //....... }); }) ...

  7. hibernate之实体@onetomany和@manytoone双向注解(转)

    下面是User类: @onetomany @Entity @Table(name="user") public class User implements Serializable ...

  8. C# HelpPage 接口文档配置

    1.打开项目路径如下的类文件: 1.1.找类方法 Register 下的 config.SetDocumentationProvider 并取消注释,修改 ~/App_Data/XmlDocument ...

  9. 将Word表格中单元格中的文字替换成对应的图片

    示例 原文件结构: 替换后文档结构: 软件截图: 代码: using System;using System.Collections.Generic;using System.ComponentMod ...

  10. MySQL 参数- Innodb_File_Per_Table(独立表空间)

    Innodb存储引擎可将所有数据存放于ibdata*的共享表空间,也可将每张表存放于独立的.ibd文件的独立表空间.共享表空间以及独立表空间都是针对数据的存储方式而言的. 共享表空间某一个数据库的所有 ...