SpringBoot集成Shiro并用MongoDB做Session存储
之前项目鉴权一直使用的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版本是
- <shiro.version>1.2.3</shiro.version>
添加依赖:
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>${shiro.version}</version>
- </dependency>
- <dependency>
- <groupId>org.mongodb</groupId>
- <artifactId>mongo-java-driver</artifactId>
- <version>3.0.0</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-mongodb</artifactId>
- <version>1.7.0.RELEASE</version>
- </dependency>
然后在application.xml或yml中配置mongodb
- spring.data.mongodb.host=127.0.0.1
- spring.data.mongodb.port=27017
- spring.data.mongodb.database=SHIRO_INFO
配置完成之后我们开始正式写Shiro认证的代码,先自定义一个鉴权realm,继承自AuthorizingRealm
- public class ShiroDbRealm extends AuthorizingRealm {
- /**
- * 用户信息操作
- */
- private SystemUserService systemUserService;
- public ShiroDbRealm() {}
- public ShiroDbRealm(SystemUserService systemUserService) {
- this.systemUserService = systemUserService;
- }
- /**
- * 授权信息
- */
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- SimpleAuthorizationInfo info = (SimpleAuthorizationInfo) ShiroKit.getShiroSessionAttr("perms");
- if (null != info && !CollectionUtils.isEmpty(info.getRoles())
- && !CollectionUtils.isEmpty(info.getStringPermissions())) {
- return info;
- }
- return null;
- }
- /**
- * 认证信息
- */
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
- throws AuthenticationException {
- UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
- String userName = token.getUsername();
- if (userName != null && !"".equals(userName)) {
- SystemUser key = new SystemUser();
- key.setLoginName(token.getUsername());
- key.setPassword(String.valueOf(token.getPassword()));
- SystemUser user = systemUserService.login(key);
- if (user != null) {
- Subject userTemp = SecurityUtils.getSubject();
- userTemp.getSession().setAttribute("userId", user.getId());
- userTemp.getSession().setAttribute("userName", user.getUserName());
- return new SimpleAuthenticationInfo(user.getLoginName(), user.getPassword(), getName());
- }
- }
- return null;
- }
- }
存储session进mongodb的Repository和实现:
- public interface ShiroSessionRepository {
- /**
- *
- * @param session
- */
- void saveSession(Session session);
- ......
- }
MongoDBSessionRepository.java
- public class MongoDBSessionRepository implements ShiroSessionRepository {
- private MongoTemplate mongoTemplate;
- public MongoDBSessionRepository() {}
- public MongoDBSessionRepository(MongoTemplate mongoTemplate) {
- this.mongoTemplate = mongoTemplate;
- }
- @Override
- public void saveSession(Session session) {
- if (session == null || session.getId() == null) {
- return;
- }
- SessionBean bean = new SessionBean();
- bean.setKey(getSessionKey(session.getId()));
- bean.setValue(SerializeUtil.serialize(session));
- bean.setPrincipal(null);
- bean.setHost(session.getHost());
- bean.setStartTimestamp(session.getStartTimestamp());
- bean.setLastAccessTime(session.getLastAccessTime());
- bean.setTimeoutTime(getTimeoutTime(session.getStartTimestamp(), session.getTimeout()));
- mongoTemplate.insert(bean);
- }
- ......
- }
ShiroSessionDAO.java
- public class ShiroSessionDAO extends AbstractSessionDAO {
- /**
- * 日志记录器
- */
- private static final Logger log = LoggerFactory.getLogger(ShiroSessionDAO.class);
- /**
- * 数据库存储
- */
- private ShiroSessionRepository shiroSessionRepository;
- /**
- *
- * @return
- */
- public ShiroSessionRepository getShiroSessionRepository() {
- return shiroSessionRepository;
- }
- /**
- *
- * @param shiroSessionRepository
- */
- public void setShiroSessionRepository(ShiroSessionRepository shiroSessionRepository) {
- this.shiroSessionRepository = shiroSessionRepository;
- }
- @Override
- public void update(Session session) throws UnknownSessionException {
- getShiroSessionRepository().updateSession(session);
- }
- @Override
- public void delete(Session session) {
- if (session == null) {
- log.error("session can not be null,delete failed");
- return;
- }
- Serializable id = session.getId();
- if (id != null) {
- getShiroSessionRepository().deleteSession(id);
- }
- }
- @Override
- public Collection<Session> getActiveSessions() {
- return getShiroSessionRepository().getAllSessions();
- }
- @Override
- protected Serializable doCreate(Session session) {
- Serializable sessionId = this.generateSessionId(session);
- this.assignSessionId(session, sessionId);
- getShiroSessionRepository().saveSession(session);
- return sessionId;
- }
- @Override
- protected Session doReadSession(Serializable sessionId) {
- return getShiroSessionRepository().getSession(sessionId);
- }
- }
OK!所有基础类已经完成,最后写一个config用来全部初始化和配置Shiro
- @Configuration
- public class ShiroConfig {
- @Resource
- private MongoTemplate mongoTemplate;
- @Resource
- private SystemUserService systemUserService;// 这是用来判断用户名和密码的service
- @Bean
- public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
- ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
- shiroFilterFactoryBean.setSecurityManager(securityManager);
- shiroFilterFactoryBean.setLoginUrl("/login");
- shiroFilterFactoryBean.setSuccessUrl("/index");
- shiroFilterFactoryBean.setUnauthorizedUrl("/403");
- // 拦截器.
- Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
- filterChainDefinitionMap.put("/static/**", "anon");
- filterChainDefinitionMap.put("/ajaxLogin", "anon");
- filterChainDefinitionMap.put("/libs/**", "anon");
- filterChainDefinitionMap.put("/images/**", "anon");
- filterChainDefinitionMap.put("/logout", "logout");
- filterChainDefinitionMap.put("/**", "authc");
- shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
- return shiroFilterFactoryBean;
- }
- public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
- DefaultWebSecurityManager securityManager) {
- AuthorizationAttributeSourceAdvisor adv = new AuthorizationAttributeSourceAdvisor();
- adv.setSecurityManager(securityManager);
- return adv;
- }
- @Bean
- public DefaultWebSecurityManager securityManager(DefaultWebSessionManager sessionManager,
- ShiroDbRealm myShiroRealm) {
- DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
- // 设置realm.
- securityManager.setRealm(myShiroRealm);
- securityManager.setSessionManager(sessionManager);
- return securityManager;
- }
- /**
- * 身份认证realm; (这里传递systemUserService给自定义的ShiroDbRealm初始化)
- *
- * @return
- */
- @Bean
- public ShiroDbRealm myShiroRealm() {
- ShiroDbRealm myShiroRealm = new ShiroDbRealm(systemUserService);
- return myShiroRealm;
- }
- @Bean
- public DefaultWebSessionManager sessionManager(ShiroSessionDAO shiroSessionDao) {
- DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
- sessionManager.setGlobalSessionTimeout(1800000l);
- sessionManager.setDeleteInvalidSessions(true);
- sessionManager.setSessionValidationSchedulerEnabled(true);
- sessionManager.setSessionDAO(shiroSessionDao);
- sessionManager.setSessionIdCookieEnabled(true);
- SimpleCookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
- cookie.setHttpOnly(true);
- cookie.setMaxAge(1800000);
- sessionManager.setSessionIdCookie(cookie);
- return sessionManager;
- }
- @Bean
- public ShiroSessionDAO shiroSessionDao(MongoDBSessionRepository shiroSessionRepository) {
- ShiroSessionDAO dao = new ShiroSessionDAO();
- dao.setShiroSessionRepository(shiroSessionRepository);
- return dao;
- }
- @Bean
- MongoDBSessionRepository shiroSessionRepository() {
- MongoDBSessionRepository resp = new MongoDBSessionRepository(mongoTemplate);
- return resp;
- }
- }
好了,大功告成,这里只是一个简单的配置,代码也是我从项目里面节选和修改过的,至于在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存储的更多相关文章
- SpringBoot集成Shiro 实现动态加载权限
一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...
- SpringBoot学习笔记(五):SpringBoot集成lombok工具、SpringBoot集成Shiro安全框架
SpringBoot集成lombok工具 什么是lombok? 自动生成setget方法,构造函数,打印日志 官网:http://projectlombok.org/features/index. 平 ...
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- springboot集成shiro 实现权限控制(转)
shiro apache shiro 是一个轻量级的身份验证与授权框架,与spring security 相比较,简单易用,灵活性高,springboot本身是提供了对security的支持,毕竟是自 ...
- 【Shiro】SpringBoot集成Shiro
项目版本: springboot2.x shiro:1.3.2 Maven配置: <dependency> <groupId>org.apache.shiro</grou ...
- SpringBoot集成Shiro安全框架
跟着我的步骤:先运行起来再说 Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc 一:导包 <!-- Shiro安全框架 ...
- springboot集成redis使用redis作为session报错ClassNotFoundException类RememberMeServices
springboot 集成redis使用redis作为缓存,会报错的问题. 错误信息: java.lang.IllegalStateException: Error processing condit ...
- SpringBoot集成Shiro实现权限控制
Shiro简介 Apache Shiro是一个功能强大且易于使用的Java安全框架,用于执行身份验证,授权,加密和会话管理.使用Shiro易于理解的API,您可以快速轻松地保护任何应用程序-从最小的移 ...
- springboot 集成shiro
首先看下shiro configuration 的配置,重要部分用红色标出了 package cn.xiaojf.today.shiro.configuration; import at.pollux ...
随机推荐
- 小甲鱼OD学习第12讲
这次我们的任务是破解这个需要特定的注册码的软件,如下图 我们从字符串入手,输入register,搜索 我们点击 查找下一个,看看有什么有用的字符串,如下图 然后,在下方,我们发现了 Regis ...
- 损失函数 hinge loss vs softmax loss
1. 损失函数 损失函数(Loss function)是用来估量你模型的预测值 f(x) 与真实值 Y 的不一致程度,它是一个非负实值函数,通常用 L(Y,f(x)) 来表示. 损失函数越小,模型的鲁 ...
- 单用户模式与救援模式:linux学习第三篇
单用户模式 1. 重新启动,在下列界面选项第一项按 e 按e后进入此grub界面(启动工具) 2. 找到linux16所在行,将'ro'(只读)修改为'rw'(读写),并加上 in ...
- selenium2 python自动化测试实战(回归测试)
selenium2 python自动化测试实战 最近接手商城的项目,针对后台测试,功能比较简单,但是流程比较繁多,涉及到前后台的交叉测试.在对整个项目进行第一轮测试完成之后,考虑以后回归测试任务比较重 ...
- checkbox/input文本框与文字对齐
3种方法都能实现checkbox文本框或radio文本框与文字对齐: <meta charset="utf-8"> <input style="vert ...
- easyui datagrid 右边框被隐藏
问题前: 如下图: 解决思路: 待文档加载完成后再执行dategrid函数 $(function () { $("#tt").datagrid({ //....... }); }) ...
- hibernate之实体@onetomany和@manytoone双向注解(转)
下面是User类: @onetomany @Entity @Table(name="user") public class User implements Serializable ...
- C# HelpPage 接口文档配置
1.打开项目路径如下的类文件: 1.1.找类方法 Register 下的 config.SetDocumentationProvider 并取消注释,修改 ~/App_Data/XmlDocument ...
- 将Word表格中单元格中的文字替换成对应的图片
示例 原文件结构: 替换后文档结构: 软件截图: 代码: using System;using System.Collections.Generic;using System.ComponentMod ...
- MySQL 参数- Innodb_File_Per_Table(独立表空间)
Innodb存储引擎可将所有数据存放于ibdata*的共享表空间,也可将每张表存放于独立的.ibd文件的独立表空间.共享表空间以及独立表空间都是针对数据的存储方式而言的. 共享表空间某一个数据库的所有 ...