当前位置: 移动技术网 > IT编程>开发语言>Java > Spring Boot集成Shiro并利用MongoDB做Session存储的方法详解

Spring Boot集成Shiro并利用MongoDB做Session存储的方法详解

2019年07月19日  | 移动技术网IT编程  | 我要评论

前言

shiro是一个权限框架,具体的使用可以查看其官网 http://shiro.apache.org/ 它提供了很方便的权限认证和登录的功能.

而springboot作为一个开源框架,必然提供了和shiro整合的功能!

之前项目鉴权一直使用的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里面怎么使用,怎么做不同权限的鉴权工作那就在自己的代码里面实现就行。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网