SpringBoot+shiro解决前后端分离session过期问题

本文详细介绍了如何在项目中使用Shiro进行权限管理,包括自定义访问控制拦截器AccessControlFilter,配置ShiroConfig,以及创建自定义GunsUserFilter过滤器。同时,展示了如何设置登录和未授权URL,以及如何通过拦截器参数控制资源访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、自定义访问控制拦截器:AccessControlFilter,集成这个接口后要实现下面这三个方法。

abstract boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception;  

boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception; 

abstract boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception;  

2、在ShiroConfig加以下代码

  @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        shiroFilter.setLoginUrl("/toLogin");
        shiroFilter.setUnauthorizedUrl("/");

        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/login/**", "anon"); //登陆
        filterMap.put("/kaptcha", "anon");  //验证码
        filterMap.put("/global/*", "anon");  //全局路径(错误或者超时)

        filterMap.put("/favicon.ico", "anon");
        filterMap.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

3、自定义GunsUserFilter

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.gizhi.guns.core.intercept;
import com.gizhi.guns.core.enumeration.RetEnum;
import com.gizhi.guns.core.util.R;
import com.gizhi.guns.core.util.RenderUtil;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

/**
 * Filter that allows access to resources if the accessor is a known user, which is defined as
 * having a known principal.  This means that any user who is authenticated or remembered via a
 * 'remember me' feature will be allowed access from this filter.
 * <p/>
 * If the accessor is not a known user, then they will be redirected to the {@link #setLoginUrl(String) loginUrl}</p>
 *
 * @since 0.9
 */
public class GunsUserFilter extends AccessControlFilter {

    /**
     *
     * 表示是否允许访问;mappedValue就是[urls]配置中拦截器参数部分,如果允许访问返回true,否则false;
     * (感觉这里应该是对白名单(不需要登录的接口)放行的)
     * 如果isAccessAllowed返回true则onAccessDenied方法不会继续执行
     * 这里可以用来判断一些不被通过的链接(个人备注)
     * * 表示是否允许访问 ,如果允许访问返回true,否则false;
     * @param request
     * @param response
     * @param mappedValue 表示写在拦截器中括号里面的字符串 mappedValue 就是 [urls] 配置中拦截器参数部分
     * @return
     * @throws Exception
     * */

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {


        if (isLoginRequest(request, response)) {
            return true;
        } else {
            Subject subject = getSubject(request, response);
            // If principal is not null, then the user is known and should be allowed access.
            return subject.getPrincipal() != null;
        }
    }

    /**
     * 表示当访问拒绝时是否已经处理了;如果返回true表示需要继续处理;如果返回false表示该拦截器实例已经处理了,将直接返回即可。
     * onAccessDenied是否执行取决于isAccessAllowed的值,如果返回true则onAccessDenied不会执行;如果返回false,执行onAccessDenied
     * 如果onAccessDenied也返回false,则直接返回,不会进入请求的方法(只有isAccessAllowed和onAccessDenied的情况下)
     * */
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpServletResponse = WebUtils.toHttp(response);

        //前端http请求中code为403的时候跳转到登陆页,R.fail()为你返回给前端的json对象
        RenderUtil.renderJson(httpServletResponse, R.fail(RetEnum.LOGIN_EXPIRED.getRet(),RetEnum.LOGIN_EXPIRED.getMsg()));

        return false;

    }
}

4、RenderUtil.java

package com.gizhi.guns.core.util;

import com.alibaba.fastjson.JSON;
import com.gizhi.guns.core.exception.GunsException;
import com.gizhi.guns.core.exception.GunsExceptionEnum;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class RenderUtil {

    /**
     * 渲染json对象
     */
    public static void renderJson(HttpServletResponse response, Object jsonObject) {
        try {
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(jsonObject));
        } catch (IOException e) {
            throw new GunsException(GunsExceptionEnum.WRITE_ERROR);
        }
    }
}

<think>我们正在分析一个基于多种技术栈构建的应用平台的整体架构设计。根据用户描述,系统使用了以下技术:后端:SpringBoot,SpringMVC,Shiro,MyBatis前端:Vue,Vuex,VueRouter,Axios,Element数据层:MySQL,Ehcache整体架构设计通常采用分层架构,包括表示层(前端)、业务逻辑层(后端)和数据访问层(数据层)。下面我们逐一解析各层使用的技术及其作用。###1.后端技术栈-**SpringBoot**:作为基础框架,提供快速配置和启动Spring应用的能力,简化了传统Spring应用的初始搭建和开发过程。-**SpringMVC**:作为Web层框架,处理HTTP请求和响应,实现MVC(Model-View-Controller)模式,负责请求的路由和视图解析(但在前后端分离架构中,后端通常只提供API,视图由前端负责)。-**Shiro**:安全框架,负责认证(Authentication)、授权(Authorization)、加密(Cryptography)和会话管理(SessionManagement)等安全功能。-**MyBatis**:持久层框架,用于操作数据库,通过XML或注解配置SQL映射,实现对象关系映射(ORM)。###2.前端技术栈-**Vue**:渐进式JavaScript框架,用于构建用户界面,采用组件化开发模式。-**Vuex**:状态管理库,用于集中管理Vue应用中多个组件共享的状态。-**VueRouter**:路由管理器,实现单页面应用(SPA)中的页面导航。-**Axios**:基于Promise的HTTP客户端,用于前端与后端API的异步通信。-**Element**:基于Vue的UI组件库,提供丰富的可复用组件,加速前端界面开发。###3.数据层技术-**MySQL**:关系型数据库管理系统,用于持久化存储业务数据。-**Ehcache**:纯Java的进程内缓存框架,用于缓存数据以提高系统性能,减少对数据库的访问压力。###系统架构工作流程1.**用户请求流程**:-用户通过浏览器访问前端应用(Vue构建的SPA)。-前端通过VueRouter解析路由,加载相应组件。-组件中通过Axios发送HTTP请求到后端API(SpringMVC控制器)。-后端控制器接收到请求后,调用服务层处理业务逻辑。-服务层可能通过MyBatis访问MySQL数据库,或使用Ehcache缓存数据。-服务层处理完成后,将结果返回给控制器,控制器再以JSON格式返回给前端。-前端接收到响应后,通过Vuex更新状态,并重新渲染组件。2.**安全控制流程**:-用户登录时,前端发送认证请求到后端。-后端Shiro进行身份认证(如验证用户名密码),成功后生成Token(或Session)并返回给前端。-后续请求中,前端携带Token(通常放在HTTPHeader中),后端Shiro进行权限校验(如访问控制、角色验证)。3.**数据缓存流程**:-当服务层需要查询数据时,先检查Ehcache中是否存在缓存数据。-如果存在,直接返回缓存数据;否则查询数据库,并将结果缓存到Ehcache中(设置合适的过期策略)。###架构特点-**前后端分离**:前后端通过API交互,职责清晰,便于独立开发和部署。-**分层设计**:各层技术分工明确,便于维护和扩展。-**模块化**:前端采用Vue组件化,后端通常采用模块化设计(如按功能划分模块)。-**安全性**:通过Shiro框架提供全面的安全控制。-**性能优化**:使用Ehcache减少数据库访问,提高响应速度。###可能的架构图```plaintext+-----------------++-----------------++-----------------++-----------------+|前端||后端||数据层||安全||(Vue,Vuex,|<----->|(SpringBoot,|<----->|(MySQL)||(Shiro)||VueRouter,|API|SpringMVC,||||||Axios,Element)||MyBatis)|<------|(Ehcache)|<------||+-----------------++-----------------++-----------------++-----------------+```###相关技术组合说明-**SpringBoot+MyBatis**:提供快速开发持久层的能力,MyBatis的SQL灵活性适合复杂查询。-**Vue全家桶(Vue+Vuex+VueRouter)**:构建现代化的单页面应用。-**Shiro集成**:与SpringBoot结合,通过注解或URL配置实现细粒度权限控制。###注意事项-在微服务架构中,上述技术栈可能用于单个微服务,而用户提到的平台可能是单体应用或微服务架构中的一个服务。根据引用[1]和[2],用户可能也关注微服务架构,但当前问题描述的技术栈更偏向于单体应用或一个独立的服务模块。###引用说明在解析中,我们参考了用户提供的引用内容,特别是关于技术栈的描述[^1][^2][^3],但主要依据用户本次问题中明确的技术栈进行分析。§§相关问题§§1.在前后端分离架构中,如何设计API接口以保证安全性和高效性?2.Shiro和SpringSecurity在安全控制方面有何区别?如何选择?3.如何优化MyBatis与Ehcache的集成以提高数据库访问性能?4.Vuex在大型前端应用中管理状态有哪些最佳实践?5.如何设计一个基于SpringBoot和Vue的权限管理系统(包括菜单、按钮权限)?</think>### 基于多技术栈的应用平台架构解析 该平台采用**前后端分离架构**,结合经典Java后端生态与现代化Vue前端框架,以下是分层解析: #### 一、后端架构层(SpringBoot + SpringMVC + Shiro + MyBatis) 1. **SpringBoot核心** - 提供自动配置、快速启动能力 - 整合各模块依赖(如Shiro安全框架、MyBatis ORM) - 管理服务生命周期:`@SpringBootApplication`启动嵌入式Tomcat 2. **SpringMVC请求处理** - 控制器层(`@RestController`)接收前端Axios请求 - 路由分发:`@RequestMapping`定义API端点 - 数据序列化:Jackson库转换JSON ↔ Java对象 3. **Shiro安全控制** - 认证流程:`Realm`实现用户密码验证 - 授权机制:`@RequiresRoles`控制接口访问权限 - 会话管理:分布式Session存储(常集成Redis) 4. **MyBatis数据持久化** - SQL映射:XML/注解定义`Mapper`接口 - 事务管理:`@Transactional`注解声明式事务 - 连接池:Druid监控SQL性能 #### 二、前端架构层(Vue + Vuex + Vue Router) 1. **Vue组件化开发** - 单文件组件(`.vue`)结构:`<template>`, `<script>`, `<style>` - Element UI组件库:表格/表单/弹窗等预制组件 2. **状态管理(Vuex)** ```javascript // store模块示例 const store = new Vuex.Store({ state: { userInfo: null }, mutations: { SET_USER(state, payload) { state.userInfo = payload } }, actions: { login({ commit }, credentials) { return axios.post('/api/login', credentials) .then(res => commit('SET_USER', res.data)) } } }) ``` 3. **路由控制(Vue Router)** - 动态路由:根据权限生成可访问路由表 - 导航守卫:`beforeEach`拦截未认证访问 #### 三、数据层(MySQL + Ehcache) 1. **MySQL存储** - 主从读写分离提升并发能力 - InnoDB引擎保障事务一致性 2. **Ehcache缓存优化** - 二级缓存:MyBatis集成减少数据库查询 - 缓存策略:`timeToLiveSeconds`控制过期时间 ```xml <!-- MyBatis配置示例 --> <cache type="org.mybatis.caches.ehcache.EhcacheCache"> <property name="timeToIdleSeconds" value="3600"/> </cache> ``` #### 四、系统交互流程 ```mermaid graph LR A[浏览器] --> B(Vue前端) B -->|Axios请求| C[SpringMVC控制器] C -->|Shiro鉴权| D[Service业务层] D -->|MyBatis调用| E[Ehcache] E -->|缓存未命中| F[MySQL数据库] F --> E --> D --> C --> B --> A ``` #### 架构优势 1. **前后端解耦**:独立开发部署,API契约定义交互 2. **安全可控**:Shiro RBAC模型实现细粒度权限 3. **性能优化**:Ehcache减少DB压力,Vue虚拟DOM提升渲染效率 4. **扩展性**:SpringBoot Starter机制支持模块化扩展 > 参考典型实现:RuoYi-Cloud采用类似架构实现分布式微服务[^1],若依平台展示SpringBoot+MyBatis+Vue的权限管理方案[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值