定时任务里调用SecurityUtils.getSubject()方法报错

来源于网络9个月前问答39
美国200G高防现已上架 性价比之王中王 大宽带 CN2直连 高性能 感受不一般香港到大陆最快线路 誉为【站群王】赠天机盾防CC 限时限购低至5折!立即抢购!

ssm项目+shiro
配置了定时任务如下:

<bean name="Job" class="bpp.controller.Job"/>
    <bean id="job" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!-- 执行的类 -->
        <property name="targetObject">
            <ref bean="Job"/>
        </property>
        <!-- 类中的方法 -->
        <property name="targetMethod">
            <value>getData</value>
        </property>
    </bean>

想要在定时任务里获取当前登录信息,所以:
User user=(User) SecurityUtils.getSubject().getPrincipal();
但是报错:

Caused by: 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.<init>(Subject.java:626)
    at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56)

不知道为啥,其他controller都能用,排除网上说的filter没配好,就是定时任务没法获取,听说是Thread的问题,不知道为啥,有没有大佬知道。。。错在哪,怎么获取登录信息啊。。。多谢多谢

debug到源码,就是获取不到securityManager

 SecurityManager securityManager = ThreadContext.getSecurityManager();
        if (securityManager == null) {
            securityManager = SecurityUtils.securityManager;
        }
        if (securityManager == null) {
            String msg = "No SecurityManager accessible to the calling code, either bound to the " +
                    ThreadContext.class.getName() + " or as a vm static singleton.  This is an invalid application " +
                    "configuration.";
            throw new UnavailableSecurityManagerException(msg);
        }

就是ThreadContext.getSercurity为null,再往下走:

 public static SecurityManager getSecurityManager() {
        return (SecurityManager) get(SECURITY_MANAGER_KEY);
    }

虽然是打了断点,但是好像断点对定时任务没用,看不到具体的空值:

public static Object get(Object key) {
        if (log.isTraceEnabled()) {
            String msg = "get() - in thread [" + Thread.currentThread().getName() + "]";
            log.trace(msg);
        }

        Object value = getValue(key);
        if ((value != null) && log.isTraceEnabled()) {
            String msg = "Retrieved value of type [" + value.getClass().getName() + "] for key [" +
                    key + "] " + "bound to thread [" + Thread.currentThread().getName() + "]";
            log.trace(msg);
        }
        return value;
    }

当前线程不可能获取不到,所以就是当前线程找不到指定的key但是,为啥,是因为定时任务给自己新开了一个独立的线程,而这个线程和用户登录的那个线程无关吗。。。唉,心累

先说,我不知道定时中怎么获取,但我认为你的方法有问题。
1.定时任务是跑在服务端的任务调度,和有没有用户登录、用户登不登陆完全没关系
2.SecurityUtils获取用户信息的使用,肯定要在一次网络请求的上下文中,不然连用户这个概念都找不到
我觉得这个设计逻辑不正确,应该要换一下吧

你应该是用的shiro框架,shiro框架这个方法可以在普通类中获取到的前提是,此为一个有效的http连接,或者tcp连接,而在定时任务里,不是http连接,也不是tcp连接,自然获取不到,

既然是idea,我建议你直接debug到源码。

【版权说明:本篇文章基于互联网CC-BY-NC-SA分享协议;如需转载时请注明出处及相应链接!】

美国200G高防现已上架 性价比之王中王 大宽带 CN2直连 高性能 感受不一般香港到大陆最快线路 誉为【站群王】赠天机盾防CC 限时限购低至5折!立即抢购!

相关文章

Sytem.IO.IOException:文件“XXX”正由另一进程使用,因此该进程无法访问该文件

程序是这样的 public struct Point { public double X; public double...

ajaxSubmit函数不执行

ajaxSubmit函数不执行

1.测试时如果是用button触发script,则不会上传文件,如果用submit触发,则直接跳转到form的action地址,总之就是在ajaxSubmit函数的位置卡住,后续代码也无法执行。 2...

C语言的一个简单小程序,各位大佬帮帮忙

八个同学的语文数学成绩 每位同学的语文数学成绩比较,如果成绩都大于等于,则输出1;否则输出0. 最后形成一个八行八列的矩阵 #include <stdio.h> int main() {...

一个打印机连续打印的问题

电脑3联打印纸241x93mm(3等分),电脑网页每一块大小需要设置为多少刚好填充满 怎么计算电脑端的高和宽,和电脑dpi,打印机dpi有关吗? 纸规格和下面这张图说的一样241x93mm(3等分...

C# datagridview的复合标题如何设置

C# datagridview的复合标题如何设置

1.问题: 如下图所示的datagridview的符合标题如何设置 2.背景: 工具一启动就显示如图所示的设置 3.解决方案:...

关于java数据类型转换的问题

关于java数据类型转换的问题

下面的这段代码为什么会报错       第五行显示报错 这里我理解不了为什么会显示溢出 第五行在进行运算的时候右边的a和b同时提升为int数据类型,那么最终第五行右边得到的结果因该是一个为13...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。