因为我司项目重构,我负责编写了一些模块,而每个模块Controller都有list,add等相同的方法,他们并不需要处理业务逻辑,只是将请求转到Service层处理完后,根据返回结果再转到相应的视图。所以我编写了Controller层的抽象类,并且在抽象类中实现常用的方法的方法且标记此类的常用注解@RequestMapping("/list")。
然后其他的所有想要具有 普通CRUD功能的Controller都继承这个抽象类,那就完全不用再写一遍了,而且根据类上的@RequestMapping 注解即可自动分路径,节约大量工作时间,和维护时间,每个类只需要设置自己的视图地址即可,将转发功能再向上提了一层。
而在这里出了个问题,我司使用Shiro作为权限管理,而@RequiresPermissions注解目前还不能直接写在类上,只能针对某个方法进行注解,这就导致我的抽象类完不能工作了,于是有了本文。
首先我们先找到shiro进行权限处理的入口,可是我并不知道怎么找。。。于是我想到让他报错,然后看请求栈肯定能找到。
严重: Servlet.service() for servlet [spring] in context with path [] threw exception [Request processing failed; nested exception is org.apache.shiro.authz.UnauthenticatedException: This subject is anonymous - it does not have any identifying principals and authorization operations require an identity to check against. A Subject instance will acquire these identifying principals automatically after a successful login is performed be executing org.apache.shiro.subject.Subject.login(AuthenticationToken) or when 'Remember Me' functionality is enabled by the SecurityManager. This exception can also occur when a previously logged-in Subject has logged out which makes it anonymous again. Because an identity is currently not known due to any of these conditions, authorization is denied.] with root cause
org.apache.shiro.authz.AuthorizationException: Not authorized to invoke method: public com.component.response.RespJSON com.web.mvc.business.ProductController.listJson(java.util.Map,java.lang.Integer,java.lang.Integer)
at org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor.assertAuthorized(<span style="color:#FF0000;">AuthorizingAnnotationMethodInterceptor.java:90</span>)
at org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor.assertAuthorized(AnnotationsAuthorizingMethodInterceptor.java:100)
at org.apache.shiro.authz.aop.AuthorizingMethodInterceptor.invoke(AuthorizingMethodInterceptor.java:38)
at org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor.invoke(AopAllianceAnnotationsAuthorizingMethodInterceptor.java:115)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:646)
at com.web.mvc.business.ProductController$$EnhancerByCGLIB$$76eb0343.listJson(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931)
at org.springframework.web.servlet.FrameworkServlet