栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java > SpringBoot

SpringBoot集成Shiro并用MongoDB做Session存储

SpringBoot 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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版本是

1.2.3

添加依赖:


    org.apache.shiro
    shiro-core
    ${shiro.version}
    org.apache.shiro
    shiro-web
    ${shiro.version}
    org.apache.shiro
    shiro-spring
    ${shiro.version}
    org.mongodb
      mongo-java-driver
      3.0.0
  
  org.springframework.data
  spring-data-mongodb
  1.7.0.RELEASE

然后在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 {  
  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; 
 public ShiroSessionRepository getShiroSessionRepository() {   return 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 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

@Configurationpublic 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 filterChainDefinitionMap = new linkedHashMap();
    filterChainDefinitionMap.put("/static
  @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里面怎么使用,怎么做不同权限的鉴权工作那就在自己的代码里面实现就行。

文章来源:
http://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/



作者:小红牛
链接:https://www.jianshu.com/p/813a1f6733ed


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/235398.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号