gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 26 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Spring Boot集成Shiro并利用MongoDB做Session存储的方法详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

前言 。

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

?
1
<shiro.version> 1.2 . 3 </shiro.version>

添加依赖:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<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 。

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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和实现:

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

MongoDBSessionRepository.java 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@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里面怎么使用,怎么做不同权限的鉴权工作那就在自己的代码里面实现就行.

总结 。

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

原文链接:http://www.tianshangkun.com/2017/11/10/SpringBoot集成Shiro并用MongoDB做Session存储 。

最后此篇关于Spring Boot集成Shiro并利用MongoDB做Session存储的方法详解的文章就讲到这里了,如果你想了解更多关于Spring Boot集成Shiro并利用MongoDB做Session存储的方法详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com