shiro 无权限跳转时 后台报错

无悔这一生 发布于 2012/03/14 20:22
阅读 27K+
收藏 3

【Gopher China万字分享】华为云的Go语言云原生实战经验!>>>

项目的框架 是采用Extjs4+springMVC+Mybatis+jdk6+tomcat6

web.xml配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<display-name>TF</display-name>
	<description>TF</description>
	
	<!-- shiro  filter-name对应applicationContext.xml中定义的名字为“shiroFilter”的bean -->
	<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>
	</filter>
	<!-- 使用“/*”匹配所有请求,保证所有的可控请求都经过Shiro的过滤。通常这个filter-mapping
		放置到最前面(其他filter-mapping前面),保证它是过滤器链中第一个起作用的 -->
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<servlet>
		<servlet-name>install</servlet-name>
		<servlet-class>
			com.turingoal.core.tf.setup.InstallServlet
		</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>install</servlet-name>
		<url-pattern>/installSave.do</url-pattern>
	</servlet-mapping>

	<!--字符过滤器 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>
			org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--  Spring 全局配置文件 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/config/spring-*.xml</param-value>
	</context-param>

	<!--  Spring 容器启动监听器 -->
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>



	<!-- Spring 刷新Introspector防止内存泄露 -->
	<listener>
		<listener-class>
			org.springframework.web.util.IntrospectorCleanupListener
		</listener-class>
	</listener>

	<!--  Spring MVC 的Servlet,它将加载WEB-INF/config/spring-servlet.xml配置文件,以启动Spring MVC模块-->
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/config/spring-servlet.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<!-- url配置为/,不带文件后缀,会造成其它静态文件(js,css等)不能访问。如配为*.do,则不影响静态文件的访问 -->
	<servlet-mapping>
		<servlet-name>spring</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<!-- session超时定义,单位为分钟 -->
	<session-config>
		<session-timeout>60</session-timeout>
	</session-config>

	<!-- 配置常见错误页面 
		<error-page>
		<error-code>403</error-code>
		<location>/WEB-INF/errors/error_403.jsp</location>
		</error-page>
		<error-page>
		<error-code>404</error-code>
		<location>/WEB-INF/errors/error_404.jsp</location>
		</error-page>
		<error-page>
		<error-code>500</error-code>
		<location>/WEB-INF/errors/error_500.jsp</location>
		</error-page>
		<error-page>
		<exception-type>java.lang.NullPointerException</exception-type>
		<location>/WEB-INF/errors/error_exception.jsp</location>
		</error-page>
		
	-->



	<!-- 默认进入的页面 -->
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
	<welcome-file-list>
		<welcome-file>login.jsp</welcome-file>
	</welcome-file-list>
	<welcome-file-list>
		<welcome-file>login.html</welcome-file>
	</welcome-file-list>
</web-app>

spring-serverlet.xml文件如下所示:

<bean id="shiroFilter"
		class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<!-- 可根据项目的URL进行替换 -->
		<property name="loginUrl" value="/" />
		<property name="successUrl" value="/core/system/index" />
		<property name="unauthorizedUrl" value="/core/system/noAuth" />
		<!-- 因为每个已经定义的javax.servlet.Filter类型的bean都可以在链的定义中通过bean名
			称获取,所以filters属性不是必须出现的。但是可以根据需要通过filters属性替换filter
			实例或者为filter起别名 -->
		<!-- <property name="filters">
			<util:map>
			<entry key="anAlias" value-ref="someFilter"/>
			</util:map>
			</property> -->
		<property name="filterChainDefinitions">
			<value>
		    /core/system/**=anon
		    /core/*= perms[role:edit]  
			</value>
		</property>
	</bean>

	<bean id="securityManager"
		class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<!-- 单realm应用。如果有多个realm,使用‘realms’属性代替 -->
		<property name="realm" ref="myRealm" />
		<!-- 默认使用servlet容器session。下面是使用shiro 原生session的例子(细节请参考帮助文档)
			<property name="sessionMode" value="native"/> 
		-->
	</bean>

	<bean id="lifecycleBeanPostProcessor"
		class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

	<bean id="myRealm"
		class="com.turingoal.core.tf.shiro.ShiroAuthorizingRealm">
	</bean>
	<!-- 定义应用上下文的 javax.servlet.Filter beans。这些beans 会被上面定义的shiroFilter自
		动感知,并提供给“filterChainDefinitions”属性使用。或者也可根据需要手动的将他们添加在
		shiroFilter bean的“filters”属性下的Map标签中。 -->

	<!--  <bean id="someFilter" class="..." />-->
	<!--<bean id="anotherFilter" class="..."></bean>-->

	<!-- 开启Shiro注解的Spring配置方式的beans。在lifecycleBeanPostProcessor之后运行 -->
	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
		depends-on="lifecycleBeanPostProcessor" />
	<bean
		class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
	</bean>

同时我的ShiroAuthorizingRealm的doGetAuthorizationInfo(PrincipalCollection prin):如下所示

@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection prin) {
		//String username = prin.asList().get(0).toString();
		 String username=(String) prin.fromRealm(getName()).iterator().next();   
		SysUserinfo user = sysUserDao.getUserByName(username);
		if (user != null) {
			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
			info.addStringPermission("accout:create");
			return info;
		}else{
		return null;
		}
	}

此处,我给它赋予相应的权限,比如,此处我给它创建accout的权限

 

在SpringMVC,的actionController中,方法如下所示:

        @RequiresPermissions("accout:view")
	@RequestMapping(value = "/getRolelist")
	public @ResponseBody
	List<Map<String, Object>> findUserList() {
			return sysRoleService.findAllRolesMap();
	}

在上述代码中可以看到我没有赋予它拥有的权限,所以它不应该执行此方法,后台抛出异常信息:

严重: Servlet.service() for servlet spring threw exception

org.apache.shiro.authz.AuthorizationException: Not authorized to invoke method: public java.util.List com.turingoal.core.tf.controller.SysRoleController.findUserList()

at org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor.assertAuthorized(AuthorizingAnnotationMethodInterceptor.java:90)

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:172)

at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)

at com.turingoal.core.tf.controller.SysRoleController$$EnhancerByCGLIB$$7f3c5438_2.findUserList(<generated>)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

 

 

 

我自己的一点猜想:我在spring-servlet.xml 配置文件中我配置了如下所示:

<property name="loginUrl" value="/" />
		<property name="successUrl" value="/core/system/index" />
		<property name="unauthorizedUrl" value="/core/system/noAuth" />

属性unauthorizedUrl:应该是对应没有权限时的跳转路径,我现在的疑惑是为啥程序没有拦截到该异常,我也不知道是不是自己哪个地方配置的不正确,还希望大家指点下我!!谢谢了

加载中
1
我不会java

http://wenku.baidu.com/link?url=QPay6f9XofexOHZJdPwC8IEai0h6XzZcm6WfPCTgadWmnOVPlFzlfrEk9nmyBfbG1SQztoLzUDNIr_vVS481P2EiUsdsWkCfxi-S0XLsbJe

第25页

0
青苗
青苗
Realm 调用  SysRoleController.findUserList() 报错、没有注入 spring bean 这么用是不对的!
无悔这一生
无悔这一生
我已经注入bean了,只是没有 @RequiresPermissions("accout:view") 这个权限的时候,它就报错了,当我附给它正确的权限的时候,是可以正确访问的。
无悔这一生
无悔这一生
我已经注入bean了,当 @RequiresPermissions("accout:view")
0
青苗
青苗
Realm 普通类不能直接调用Controller 方法,你可以获得 ApplicationContext 后调用 service 层 。
无悔这一生
无悔这一生
"Realm 普通类不能直接调用Controller 方法,你可以获得 ApplicationContext 后调用 service 层" 我Realm 类 好像没有直接调用Controller的方法,不知你从哪里看出我在Realm类直接调用Controller的方法 ? 麻烦你给我讲解下,再次谢谢了!
无悔这一生
无悔这一生
哦 谢谢你哦 我自己先试试!
0
o
odde
哥们,我现在也遇到了这个问题,有没有在shiro框架内的解决方法,
0
lfl
lfl
同问啊
0
猴山老大
猴山老大
这个事没有配置shiro权限异常拦截导致的 我也搞了下 搞定了
Marshmallow
Marshmallow
指点下
HulkZ
HulkZ
求细节
0
ian003
ian003
也遇到了这个问题...
0
诠释这低调

同样遇到这问题,发现异常拦截也不起作用,页面也抓取不到,请问解决了吗?shiro对ajax异步请求不支持

0
分手在雪天

在springMvc.xml中增加一段一行拦截配置就可以了

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<prop key="org.apache.shiro.authz.UnauthorizedException">/mg/unauthorized</prop>
			</props>
		</property>
	</bean>




0
lujiawei
lujiawei

引用来自“分手在雪天”的评论

在springMvc.xml中增加一段一行拦截配置就可以了

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<prop key="org.apache.shiro.authz.UnauthorizedException">/mg/unauthorized</prop>
			</props>
		</property>
	</bean>




感谢大神,找了好久的资料,终于都解决了!
返回顶部
顶部