Shiro实战详解(3)

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
 /**
     * 1.创建shiro自带cookie对象
     */
    @Bean
    public SimpleCookie sessionIdCookie(){
        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setName("ShiroSession");
        return simpleCookie;
    }

    //2.创建realm
    @Bean
    public MyRealm getRealm() {
        return new MyRealm();
    }

    /*
    * 注入创建的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;
    }

    /**
     * 5.保证实现了Shiro内部lifecycle函数的bean执行
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 6.开启对shiro注解的支持
     *   AOP式方法级权限检查
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }

    /**
     * 7.配合DefaultAdvisorAutoProxyCreator事项注解权限校验
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager());
        return authorizationAttributeSourceAdvisor;
    }




    //8.配置shiro的过滤器工厂再web程序中,shiro进行权限控制全部是通过一组过滤器集合进行控制
   @Bean
    public ShiroFilterFactoryBean myShiroFilterFactoryBean(){

       ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();

       factoryBean.setLoginUrl("/usererror"); //认证失败去这里
       factoryBean.setSecurityManager(defaultWebSecurityManager());

       Map<String, String> map = new LinkedHashMap<>();
       //认证页面
       map.put("/login","anon");  //匿名
       map.put("/user/**","authc"); //认证后

       factoryBean.setFilterChainDefinitionMap(map);
       return factoryBean;
   }

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值