Shiro实战详解(3)

发布时间:2024年01月22日

04 Springboot集成Shiro

1、技术栈

主框架:springboot

响应层:springMVC

持久层:mybatis

事务控制:jta

前端技术:vue+ElementUI

2、数据库设计

在这里插入图片描述

sh_user:用户表,一个用户可以有多个角色

sh_role:角色表,一个角色可以有多个资源

sh_resource:资源表

sh_user_role:用户角色中间表

sh_role_resource:角色资源中间表

3、注解方式鉴权

以下为常用注解

注解说明
@RequiresAuthentication表明当前用户需是经过认证的用户
@ RequiresGuest表明该用户需为”guest”用户
@RequiresPermissions当前用户需拥有指定权限
@RequiresRoles当前用户需拥有指定角色
@ RequiresUser当前用户需为已认证用户或已记住用户

05 实现分布式会话SessionManager

1、会话的问题

在使用多个服务器,实现分布式服务时,用户在登录服务器已经登录,但是其他服务器对用户来说由于第一次访问,没有用户的会话信息,就会拦截,让他去登录,但实际上我们已经登录过了。
在这里插入图片描述

2、分布式会话实现思路

在这里插入图片描述
针对出现的session会话问题,可以使用redis来存储session会话信息,来实现共享session。

所有服务器的session信息都存储到了同一个Redis集群中,即所有的服务都将 Session 的信息存储到 Redis 集群中,无论是对 Session 的注销、更新都会同步到集群中,达到了 Session 共享的目的。

Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。

在实际工作中我们建议使用外部的缓存设备(包括Redis)来共享 Session,避免单个服务器节点挂掉而影响服务,共享数据都会放到外部缓存容器中

3、实现步骤:

1.创建RedisSessionDao extends AbstractSessionDAO
public class RedisSessionDao extends AbstractSessionDAO {

    @Autowired(required = false)
    RedisTemplate redisTemplate;

    @Override
    protected Serializable doCreate(Session session) {
        //获取sessionid
        Serializable id = generateSessionId(session); //传入参数获取id
        //调用父类方法
        assignSessionId(session,id);
        redisTemplate.opsForValue().set(id,session);
        return id;
    }

    @Override
    protected Session doReadSession(Serializable serializable) {
        return (Session) redisTemplate.opsForValue().get(serializable);
    }

    @Override
    public void delete(Session session) {
        redisTemplate.delete(session.getId());

    }
}

2.配置ShiroConfig
// 注入创建的RedisSessionDao类
@Bean
public RedisSessionDao getRedisSessionDao(){
    return  new RedisSessionDao();
}
// 3.创建会话管理器
@Bean
public DefaultWebSessionManager sessionManager(){
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();

    sessionManager.setSessionDAO(getRedisSessionDao());
    sessionManager.setSessionValidationSchedulerEnabled(false);
    sessionManager.setSessionIdCookieEnabled(true);
    sessionManager.setSessionIdCookie(sessionIdCookie());
    sessionManager.setGlobalSessionTimeout(3600000);

    return sessionManager;
}

//4.创建安全管理器
@Bean
public SecurityManager defaultWebSecurityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(getRealm());
    securityManager.setSessionManager(sessionManager());
    return securityManager;
}
文章来源:https://blog.csdn.net/ji_xin0721/article/details/135740966
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。