shiro 在未登录时候获取 SecurityUtils.getSubject() 异常

news2024/12/21 22:57:50

一、错误描述

需求背景:新项目需要通过aop将请求日志打印出来,并且附上当前登录人的账号,系统认证使用 shiro 控制,想着直接通过  SecurityUtils.getSubject() 获取当前身份,但是很不幸的是,当用户没有登录时候直接报异常了,异常信息如下

org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.

二、网上各种解决方法

 SecurityUtils.setSecurityManager(securityManager); 网上各种解决方案就是在初始化的时候将SecurityUtils 设置进去,但是我的是 xml 配置,而且这个类是抽象类,也不能设置属性;

2.1 方案1 springboot 解决

@Bean
    public SecurityManager securityManager() {

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        securityManager.setRealm(shiroRealm());
        
        //在注册bean的时候,加入下面这句话,将securityManager放到SecurityUtils里面
        SecurityUtils.setSecurityManager(securityManager);


        return securityManager;
    }

2.2 web.xml 过滤器的顺序

很多说是因为 web.xml 里面有其他过滤器在前面,导致shiro的过滤器在后面不能处理,其实我是有些不信的,尝试调整顺序,果然还是不行;

三、最终解决方案

       <dispatcher>ASYNC</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>

加上error shiro 才能接管,因为shiro 的配置都是管理 /** 的url 但是有些错误的url没有接管,但是你又从session中获取,那么当然报错了 

 <!-- 配置shiro的代理过滤器 开始 -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>shiroFilter</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <servlet-name>dispatcherServlet</servlet-name>
        <dispatcher>ASYNC</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    <!-- 配置shiro的代理过滤器 结束 -->

3.1 原因分析

org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.
    at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
    at org.apache.shiro.subject.Subject$Builder.&lt;init&gt;(Subject.java:627)
    at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56)
    ……………………
 

这是我原本配置的配置

<!-- 配置shiro的代理过滤器 开始 -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>shiroFilter</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <servlet-name>dispatcherServlet</servlet-name>
    </filter-mapping>
    <!-- 配置shiro的代理过滤器 结束 -->

  总结说明:你所请求的URL是不在Shiro所管辖范围的,而你又在你请求的这个URL后试图通过Shiro来获取Session,所以对Shiro来说“你不让我负责的事,为什么要跟我要结果”,我不能处理,我只能处理正确的url,那么我只能给你抛出异常了;

3.2 问题出现方式以及总结

当我配置了 404 的错误,定向到 404 的url 必现这个问题;

404很明显是一个ERROR,此前我没有添加 <code><dispatcher>ERROR</dispatcher>;</code>,而我在发生错误的时候又使用 SecurityUtils.getSubject().getSession() 来获取Session(我需要从会话中读取相关数据记录日志),所以被Shiro 所拒绝(抛出异常)。

--

如果你使用Shiro,并且没有配置 <dispatcher>ERROR</dispatcher> 。那么,你登录后,随便访问一个不存在的页面触发404,或者触发500这样的错误页。再回头看登录后的页面,登录状态就丢失了。因为这个时候sessionid 被重新生成覆盖了登录状态时的sessionid。


四、spring mvc 配置404 自定义页面

使用了  @ControllerAdvice 注解处理 @ExceptionHandler(NoHandlerFoundException.class) 但是根本捕获不到

@ControllerAdvice
@Slf4j
public class ExceptionAdvice {

    @ExceptionHandler(IllegalException.class)
    public @ResponseBody LayRespView permissionException(IllegalException pe) {
        return LayRespView.fail(pe.getErrCode(),pe.getMessage());
    }


    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public @ResponseBody LayRespView handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.error("参数解析失败:{}", e);
        return LayRespView.fail("400","请求参数不合法");
    }


    /**
     *  404 异常
     * @param
     * @return
     */
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoHandlerFoundException.class)
    public void handlerFoundException(NoHandlerFoundException ex,HttpServletRequest request, HttpServletResponse response) throws IOException{
        // 判断是否有登录
        if (SecurityUtils.getSubject().getPrincipal() == null) {
            try {
                response.sendRedirect("/login/toLogin.fuiou");
                return;
            } catch (IOException e) {
               log.info("重定向异常",e);
            }
        }
        // 判断请求类型是否为json
        if (request.getHeader("Content-Type").contains(MediaType.APPLICATION_JSON_VALUE)) {
            StreamUtils.writeObjectToJson(response,LayRespView.fail("404","页面找不到,请检查url是否正确"));
            return;
        }

        response.sendRedirect("/login/404.fuiou");
    }
}

4.1 处理方案

自己在 web.xml 中定义errorcode 转向自己的servlet 处理 

<error-page>
    <error-code>404</error-code>
    <location>/login/404.fuiou</location>
</error-page>

4.2 定义 404 controller

 /**
     * 404 页面
     * @return
     */
    @RequestMapping("/404.fuiou")
    public String notfound(HttpServletRequest request, HttpServletResponse response) {
        // 判断是否有登录
        if (!SecurityUtils.getSubject().isAuthenticated()) {
            return "login";
        }
        // 判断请求类型是否为json
        if (request.getHeader("Content-Type").contains(MediaType.APPLICATION_JSON_VALUE)) {
            StreamUtils.writeObjectToJson(response,LayRespView.fail("404","页面找不到,请检查url是否正确"));
            return null;
        }
        return "comm-error/404";
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2168165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

低代码BPM业务流程:简化企业流程管理的利器

什么是低代码BPM&#xff1f; 低代码BPM结合了低代码开发平台与业务流程管理的理念&#xff0c;使企业能够以较少的编码工作&#xff0c;快速设计、实施和优化业务流程。低代码平台通常提供可视化的界面&#xff0c;用户可以通过拖放组件来构建应用&#xff0c;而无需深入掌握…

linux信号 | 学习信号三步走 | 全解析信号的产生方式

前言&#xff1a;本节内容是信号&#xff0c; 主要讲解的是信号的产生。信号的产生是我们学习信号的第二个阶段。 我们已经学习过第一个阶段——信号的概念与预备知识&#xff08;没有学过的友友可以查看我的前一篇文章&#xff09;。 以及我们还没有学习信号的第三个阶段——信…

【rust】 基于rust编写wasm,实现markdown转换为html文本

文章目录 背景转换预览核心代码前置依赖rustup换源cargo换源中科大 wasm-pack安装 背景 尝试用rust编写一款markdown转html的插件&#xff0c;通过wasm给html使用&#xff0c;不得不说体积挺小&#xff0c;约200K&#xff0c; 比go的wasm起步2MB看着舒服点。 不过go的配置和换…

Nginx基础详解3(nginx.conf核心代码讲解、常用命令解析、Nginx日志切割)

续Nginx基础详解2&#xff08;首页解析过程、进程模型、处理Web请求机制、nginx.conf语法结构&#xff09;-CSDN博客 目录 8.nginx.conf核心代码 8.1错误日志 8.1.1第一列&#xff1a; 8.1.2第二列&#xff1a; 8.1.3第三列&#xff1a; 8.2 #pid 8.3http模块&#xff…

Vue引入js脚本问题记录(附解决办法)

目录 一、需求 二、import引入问题记录 三、解决方式 一、需求 我想在我的Vue项目中引入jquery.js和bootstrap.js这种脚本文件&#xff0c;但发现不能单纯的import引入&#xff0c;问题如下。 二、import引入问题记录 我直接这么引入&#xff0c;发现控制台报错TypeError: …

语义分割评价指标——95% Hausdorff距离

回顾以下95% Hausdorff距离的概念&#xff0c;一张比较经典直观的图&#xff1a; 一、 最快理解 max(d_XY, d_YX):取X>Y距离 和 Y>X距离的最大值。 其中 X>Y max min x>y :X所有点都和Y集合计算最小的距离&#xff0c;得到的距离集合再取最大值。 同理 Y>X m…

汽修行业:融合员工培训、知识库管理系统与SOP

随着汽车技术的飞速发展和消费者需求的日益多样化&#xff0c;汽修行业面临着前所未有的挑战与机遇。为了提升服务质量、增强竞争力&#xff0c;汽修企业必须重视员工培训、知识管理和作业标准化。本文旨在探讨如何构建一套集成汽修员工培训、知识库管理与SOP&#xff08;标准作…

Leetcode - 周赛416

目录 一&#xff0c;3295. 举报垃圾信息 二&#xff0c;3296. 移山所需的最少秒数 三&#xff0c;3297. 统计重新排列后包含另一个字符串的子字符串数目 I 四&#xff0c;3298. 统计重新排列后包含另一个字符串的子字符串数目 II 一&#xff0c;3295. 举报垃圾信息 本题就是…

首个端到端自动驾驶背景下对抗性训练研究

更多优质内容&#xff0c;请关注公众号&#xff1a;智驾机器人技术前线 1.论文信息 论文标题&#xff1a;Module-wise Adaptive Adversarial Training for End-to-end Autonomous Driving 作者&#xff1a;Tianyuan Zhang, Lu Wang, Jiaqi Kang, Xinwei Zhang, Siyuan Liang,…

(done 意义不明的公式) 声音信号处理基础知识(10) (Demystifying the Fourier Transform: The Intuition)

参考&#xff1a;https://www.youtube.com/watch?vXQ45IgG6rJ4 就像棱镜可以把可见光分解为不同波长的光一样&#xff0c;FT 做的事情就是把复杂的声波转为不同频率的声波 FT 可以把时域信息转为频域信息 以下是对于 FT 的一些 intuition-level 的理解&#xff1a; 1.FT 会…

2.4K star的GOT-OCR2.0:端到端OCR 模型

GOT-OCR2.0是一款新一代的光学字符识别&#xff08;OCR&#xff09;技术&#xff0c;标志着人工智能在文本识别领域的重大进步。作为一款开源模型&#xff0c;GOT-OCR2.0不仅支持传统的文本和文档识别&#xff0c;还能够处理乐谱、图表以及复杂的数学公式&#xff0c;为用户提供…

如何使用ssm实现基于JavaWeb的个人健康信息管理系统

TOC ssm701基于JavaWeb的个人健康信息管理系统jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#x…

大模型如何赋能智慧城市新发展?

国家数据局近期发布的《数字中国发展报告&#xff08;2023&#xff09;》显示&#xff0c;我国数据要素市场化改革步伐进一步加快&#xff0c;数字经济规模持续壮大&#xff0c;数字技术应用场景不断拓展。这一成就的背后是数字技术广泛应用&#xff0c;数字技术不仅影响着老百…

12.系统架构分析师应该懂的项目管理知识

进度管理 进度管理就是采用科学的方法&#xff0c;确定进度目标&#xff0c;编制进度计划和资源供应计划&#xff0c;进行进度控制&#xff0c;在与质量、成本目标协调的基础上&#xff0c;实现工期目标。具体来说&#xff0c;包含以下过程&#xff1a; 活动定义&#xff1a;…

智算中心动环监控:构建高效、安全的数字基础设施@卓振思众

在当今快速发展的数字经济时代&#xff0c;智算中心作为人工智能和大数据技术的核心支撑设施&#xff0c;正日益成为各行业实现智能化转型的重要基石。为了确保这些高性能计算环境的安全与稳定&#xff0c;卓振思众动环监控应运而生&#xff0c;成为智算中心管理的重要组成部分…

小红书,努力成为小红书

【潮汐商业评论/原创】 Lisa作为时尚达人&#xff0c;小红书就是她成长路上的「电子闺蜜」&#xff0c;“想买衣服了&#xff0c;去小红书搜一下&#xff1b;晚饭不知道吃什么&#xff0c;去小红书搜搜看&#xff1b;最近我又小红书上在研究MBTI。” “离了小红书真是不能活&…

[笔记]数据结构

文章目录 堆排序215 数组中第k个最大元素 堆排序 堆排序方法对于记录数较少的文件并不值得提倡&#xff0c;但对n较大的文件还是有效 运行时间主要耗费在&#xff1a; 建立初始堆调整建立新堆 反复筛选 筛选算法进行的关键字比较次数至多为&#xff1a; 2 ( k − 1 ) 2(k-1)…

9.26作业

C 面试题 1,什么是虚函数?什么是纯虚函数? 虚函数&#xff1a;父子类中&#xff0c;在父类中的函数需要在子类中进行重写&#xff0c;重写后父子类空间中使用的都是重写后的函数&#xff0c;该函数就是虚函数&#xff0c;虚函数的声明需要在函数前加virtual。 纯虚函数&…

Trace纳米侦查无人机技术详解

纳米无人机&#xff0c;作为微型无人机的一种&#xff0c;通常指尺寸和重量都非常小的无人机&#xff0c;其重量一般不超过几百克&#xff0c;甚至更小。这类无人机由于体积小、重量轻&#xff0c;具备高度的隐蔽性和灵活性&#xff0c;在军事侦察、环境监测、搜救行动等领域具…

数值计算 --- 平方根倒数快速算法(上)

平方根倒数快速算法(上) --- 向Greg Walsh致敬&#xff01; 写在最前面 --- 一场关于平方根倒数快速算法作者的讨论&#xff1a; 上图中的这段代码出自一个早期的3D游戏<雷神之锤>的源代码&#xff0c;它实现的功能就是计算一个数x的平方根的倒数&#xff1a; 这段代码之…