惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
L
LINUX DO - 最新话题
Cloudbric
Cloudbric
N
News and Events Feed by Topic
S
Secure Thoughts
Vercel News
Vercel News
S
Security @ Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
SegmentFault 最新的问题
Hacker News: Ask HN
Hacker News: Ask HN
博客园 - 聂微东
WordPress大学
WordPress大学
Google Online Security Blog
Google Online Security Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
PCI Perspectives
PCI Perspectives
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
Blog — PlanetScale
Blog — PlanetScale
Apple Machine Learning Research
Apple Machine Learning Research
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threat Research - Cisco Blogs
博客园 - 司徒正美
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
A
About on SuperTechFans
P
Proofpoint News Feed
大猫的无限游戏
大猫的无限游戏
V
V2EX
I
Intezer
H
Hacker News: Front Page
www.infosecurity-magazine.com
www.infosecurity-magazine.com
L
Lohrmann on Cybersecurity
F
Fortinet All Blogs
Schneier on Security
Schneier on Security
博客园 - 叶小钗
The Cloudflare Blog
月光博客
月光博客
W
WeLiveSecurity
T
Tenable Blog
P
Proofpoint News Feed
aimingoo的专栏
aimingoo的专栏
Help Net Security
Help Net Security
L
LangChain Blog
C
CERT Recently Published Vulnerability Notes
T
The Exploit Database - CXSecurity.com
美团技术团队
B
Blog

小松鼠的博客

记录一次线上k8s工作节点无法创建容器的问题排查思路与解决办法 记一次线上GoLang项目OOM排查过程 从LastPass转向拥抱开源KeePass的心路历程 故障定位与 AI 结合前后端编码实践 FileBeat收集nginx-ingress-controller日志 K8s云原生环境下文件描述符占用过高查询思路 2024年最新关闭火绒安全工具的开机自启方法 Kubernetes任务调度实践-Go语言实现Job和CronJob对比分析 离线更新k8s环境下的trivy漏洞库方法 使用Go语言接入Choerodon实现基于OAuth2的统一身份认证登录 在Vue2中自定义Switch组件并实现父子组件双向数据绑定 关于docker jdk1.8镜像中的GB18030-2022标准支持及验证 Go框架gin中的session存储gin-contrib-sessions和go-session 关于修改node_module中的源码问题记录 docker-compose网络和内网服务IP冲突问题 慎用存储过程:一条语句引发的数据库存储100%占用 Spring Boot中4种文件下载方法的实现 避坑-不能将specific类型的gitlab-runner改变为share类型 Docker compose中的MySQL主从复制模式和percona-toolkit工具使用 在minio中开启https访问以及使用rclone备份minio桶 在多机Docker环境下部署Choerodon的解决方案 Prometheus中Monitor添加对SpringBoot Actuator的Basic认证 在Nginx的容器镜像中隐藏Nginx的Server响应头 K8s中的两种nginx-ingress-controller及其区别 两个docker工具:runlike和whaler Grafana中的邮件报警和截图插件grafana-image-enderer K8s中externalName-service和services-without-selectors maven配置文件settings.xml中的一些概念总结 K8s中flexvolume插件驱动的安装 K8s中的coredns无法解析svc问题排查 K8s中使用Ingress访问请求体过大问题解决 关于k8s中对于SpringBoot应用TCP类型的就绪探针不准确的问题发现 K8s中的环境变量与应用程序的对应关系与操作 SpringMVC4升级为SpringBoot2实战 在Vmware中Ubuntu22.04的vm-tools和网络问题 修改k8s节点主机名并重新加入集群 离线安装Grafana插件 Spring Data Jpa 中使用CriteriaBuilder动态拼接SQL 在SpringBoot项目配置Liquibase数据库版本管理 记录Vue中父子组件传值的实战应用 实现单例模式的8种方法 三种常用的生产者消费者模式实现 使用两个线程交替打印0-100的奇偶数 关于部署于JBoss5中的Spring应用获取项目真实部署路径的问题 获取下一个完全对称日 通过短信验证码验证修改密码的解决方案 在Win10中使用Win+R快速启动软件 使用RSA加解密时注意Cipher.getInstance(String var0,Provider var1)提供的Provider是否正确 在RestEasy2.x中解决接口重复提交问题 几道简单的CTF题目思路 重温Spring---Spring事务控制与基于XML和注解的配置方法 重温Spring---Spring AOP基于XML和注解的配置 重温Spring---AOP动态代理和Spring AOP及其基本原理 重温Spring---Spring IOC基于XML和注解的配置和比较 在Windows10中安装MySQL5.7 Zip版本及常用配置 重温Spring---使用Spring IOC解决程序耦合 策略模式与责任链模式实战应用 Linux上直接打开war包修改文件 在Windows上运行两个微信的简单脚本 ThreadPoolExecutor的使用方法与分页查询数据实例 IDEA中Shelve Changes 和 Git Stash 通过resteasy发布RESTful接口 解决前端请求后台接口,后台报错Can not deserialize instance of java.util.ArrayList out of START_OBJECT token 使用VBA脚本汇总Excel文档 使用Jenkins+GitLab实现自动部署vue项目 Kubernetes:使用hostPath挂载nginx集群的配置文件和html 彻底搞定VirtualBox虚拟机的网络设定 在Docker中安装MySQL5.7并开启远程访问(附授权和修改密码方式) 利用git命令和java文件流 获取自己改动过的文件 浅谈Spring定时任务的使用(Scheduled注解) 在Spring项目简单配置Flyway(V4.2版本)数据库版本管理 解决Spring单元测试中因外键关联导致的失败integrity constraint violation:foreign key no action Redis安装与哨兵模式配置入门 关于Vue中使用Element-UI样式row-class-name失效的问题 Element-UI中实现可动态增加行列和可编辑单元格的表格 Windows系统查看端口占用、结束进程方法和命令 层次分析法(AHP)分析步骤与计算方法 源码分析之解决layui框架重载表格时额外参数不清空的问题 Spring Data Jpa 返回自定义对象(实体部分属性、多表联查) 如何将一个jar放到本地maven仓库中 关于SSM项目停止Tomcat时Log4j出现java.lang.NoClassDefFoundError: 获取el-table单元格值并根据该值对元素自定义样式渲染 解决Git每次push都要重新输入账号密码和HttpRequestException encountered的问题 解决前后端分离项目中Vue不带cookies的问题 SSM集成Shiro不进入自定义Realm的doGetAuthorizationInfo的解决方案 Vue+SSM中使用Token验证登录 Git拉代码推送代码提示密码错误如何修改 Git配置SSH Key(Git配置多个账户) 安装Tomcat服务器以及错误汇总(tomcat8.0、jdk8) 关于我
SSM集成Shiro自定义权限过滤器不执行解决方案
ycyin · 2020-02-12 · via 小松鼠的博客

2020年2月11日大约 5 分钟Web技术&安全SSMShiro


开发环境

  • IntelliJ IDEA 2019.3 ×64
  • Spring 4.3.3
  • Shiro 1.3.2

问题重现

在Shiro的权限认证后,如果没有权限,系统会跳转到指定的页面,这就需要如下配置:

<!-- 权限认证失败,则跳转到指定页面 -->
<property name="unauthorizedUrl" value="/unauthorized"/>

这一般用在非前后端分离的应用中,如果系统采用前后端分离架构则需要后台直接返回JSON格式的数据。在Shiro中,通常采用自定义过滤器(Filter)重写AuthorizationFilter类中的isAccessAllowedonAccessDenied方法来实现。目的是过滤器拦截到没有权限访问目标资源时,直接返回“无权限”等JSON数据。

自定义过滤器:

import java.io.IOException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import com.yyc.shiro.RespShiroResult;
import com.yyc.shiro.ShiroResultEnum;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import com.alibaba.fastjson.JSONObject;

/**
 * @ClassName:  ShiroPermsFilter
 * @Description:TODO(ShiroPermsFilter是权限认证)
 * @author: yinyicao
 *
 * @Copyright: 2020 www.yinyicao.work. All rights reserved.
 *
 */

public class ShiroPermsFilter extends AuthorizationFilter{
    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = getSubject(request, response);
        String[] perms = (String[]) mappedValue;
        boolean isPermitted = true;
        if (perms != null && perms.length > 0) {
            if (perms.length == 1) {
                if (!subject.isPermitted(perms[0])) {
                    isPermitted = false;
                }
            } else {
                if (!subject.isPermittedAll(perms)) {
                    isPermitted = false;
                }
            }
        }
        return isPermitted;
    }

    /**
     * shiro认证perms资源失败后回调方法
     * @param servletRequest
     * @param servletResponse
     * @return
     * @throws IOException
     */
    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
    	System.err.println("-----------------ShiroPermsFilter---onAccessDenied-------------------");
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json");
        RespShiroResult resultData = new RespShiroResult(ShiroResultEnum.UNAUTHORIZED);
        httpServletResponse.getWriter().write(JSONObject.toJSON(resultData).toString());
        return false;
    }


}

接着,在shiro的配置文件xml中配置和使用过滤器:

    <!-- Shiro过滤器 核心-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- Shiro的核心安全接口,这个属性是必须的 -->
        <property name="securityManager" ref="securityManager"/>

        <property name="filters">
            <map>
                <entry key="authc" value-ref="shiroLoginFilter" />
                <entry key="perms" value-ref="shiroPermsFilter" />
            </map>
        </property>

        <!-- 身份认证失败,则跳转到登录页面的配置 -->
<!--        <property name="loginUrl" value="/nologin"/>-->
        <!-- 权限认证失败,则跳转到指定页面 -->
<!--        <property name="unauthorizedUrl" value="/unauthorized"/>-->

        <!-- Shiro连接约束配置,即过滤链的定义 -->
        <property name="filterChainDefinitions">
            <value>
                /logout=logout
                <!--anon 表示匿名访问,不需要认证以及授权-->
                /main/login=anon
                <!--authc表示需要认证 没有进行身份认证是不能进行访问的,这里使用的是自定义过滤器-->
                /** =authc,perms
            </value>
        </property>

    </bean>

同时还需要在web.xml中监听shiroFilter

<!--shiro过滤器-->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

**问题来了:**访问的目标资源没有权限时,不执行自定义的权限过滤器,系统无法返回JSON数据,而是直接发生UnauthorizedExceptionUnauthenticatedException异常。具体的异常信息见文末附1。

解决问题

在折腾半天后,无论怎样也不能完成过滤器的回调,只能通过全局异常拦截的方式改正。

参考: https://blog.csdn.net/joe_storm/article/details/80375089

初步

在SpringMVC中处理异常的方式是在springmvc.xml中配置org.springframework.web.servlet.handler.SimpleMappingExceptionResolver

如下:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!-- 错误异常转发jsp页面 -->
            <prop key="org.apache.shiro.authz.UnauthorizedException">/unauthorized.jsp</prop>
            <prop key="org.apache.shiro.authz.UnauthenticatedException">/unauthenticated.jsp</prop>
        </props>
    </property>
</bean>

但是这种方式还是进行页面的跳转,不能直接返回数据。这时需要重写SimpleMappingExceptionResolver,主要是覆盖doResolveException方法。

最终

自定义异常处理,重写SimpleMappingExceptionResolver,覆盖doResolveException方法。如下:

import com.alibaba.fastjson.JSONObject;
import com.yyc.shiro.RespShiroResult;
import com.yyc.shiro.ShiroResultEnum;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义异常捕获,主要捕获没有权限异常
 */
public class NoPermissionException extends SimpleMappingExceptionResolver {

    @Override
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        if (ex instanceof  AuthorizationException || ex instanceof UnauthorizedException){
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            RespShiroResult resultData = new RespShiroResult(ShiroResultEnum.UNAUTHORIZED);
            try {
                response.getWriter().write(JSONObject.toJSON(resultData).toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else { // 其他异常打印
            ex.printStackTrace();
        }
        return null;
    }
}

然后在Spring配置文件中定义这个bean。

    <!--重写了SimpleMappingExceptionResolver中的doResolveException方法处理异常-->
    <bean class="com.yyc.exception.NoPermissionException">

    </bean>

这时候访问该用户没有权限访问的资源则会返回JSON数据了。

{
    "id": 1,
    "desc": "对不起,您无权限进行当前操作",
    "status": 401
}

附1

UnauthorizedExceptionUnauthenticatedException异常

异常信息1
异常信息1
异常信息2
异常信息2
HTTP Status 500 - Request processing failed; nested exception is org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [getBookPressData]
type Exception report

message Request processing failed; nested exception is org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [getBookPressData]

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [getBookPressData]
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	com.yyc.filter.ACAFilter.doFilter(ACAFilter.java:56)
	org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause

org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [getBookPressData]
	org.apache.shiro.authz.ModularRealmAuthorizer.checkPermission(ModularRealmAuthorizer.java:323)
	org.apache.shiro.mgt.AuthorizingSecurityManager.checkPermission(AuthorizingSecurityManager.java:137)
	org.apache.shiro.subject.support.DelegatingSubject.checkPermission(DelegatingSubject.java:205)
	org.apache.shiro.authz.aop.PermissionAnnotationHandler.assertAuthorized(PermissionAnnotationHandler.java:74)
	org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor.assertAuthorized(AuthorizingAnnotationMethodInterceptor.java:84)
	org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor.assertAuthorized(AnnotationsAuthorizingMethodInterceptor.java:100)
	org.apache.shiro.authz.aop.AuthorizingMethodInterceptor.invoke(AuthorizingMethodInterceptor.java:38)
	org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor.invoke(AopAllianceAnnotationsAuthorizingMethodInterceptor.java:115)
	org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
	com.yyc.controller.BookController$$EnhancerBySpringCGLIB$$6f4db057.getBookPressData(<generated>)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:498)
	org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:180)
	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	com.yyc.filter.ACAFilter.doFilter(ACAFilter.java:56)
	org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause

org.apache.shiro.authz.AuthorizationException: Not authorized to invoke method: public com.yyc.vo.RespMsg com.yyc.controller.BookController.getBookPressData()
	org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor.assertAuthorized(AuthorizingAnnotationMethodInterceptor.java:90)
	org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor.assertAuthorized(AnnotationsAuthorizingMethodInterceptor.java:100)
	org.apache.shiro.authz.aop.AuthorizingMethodInterceptor.invoke(AuthorizingMethodInterceptor.java:38)
	org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor.invoke(AopAllianceAnnotationsAuthorizingMethodInterceptor.java:115)
	org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
	com.yyc.controller.BookController$$EnhancerBySpringCGLIB$$6f4db057.getBookPressData(<generated>)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:498)
	org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:180)
	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
	org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	com.yyc.filter.ACAFilter.doFilter(ACAFilter.java:56)
	org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
	org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.37 logs.

Apache Tomcat/8.0.37