Shiro 注解的使用

今天研究了下shiro注解的使用,碰到了一些问题,因此将问题的解决方案记录下来。

首先需要申明的是,项目环境使用的是 SSH2框架,并且只启动了shiro的注解。

首先看下shiro给的Demo中如何开启对注解的支持:

    <!-- 配置这个Bean后,对于在spring配置文件中配置的shiro对象,会自动调用用init()方法和destory()方法。 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- 启用shiro注解的支持 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
	<!-- securityManager的配置这里没有给出 -->
        <property name="securityManager" ref="securityManager"/>
    </bean>

本以为这样配置好后,就没有什么问题了,谁项目启动后会报错, java.lang.NoSuchMethodException: com.sun.proxy.$Proxy25.test()

想必大家也看出来了,异常为找不到方法,而且这个方法还是代理方法。

仔细想下,我的Action没有实现Action接口,而是继承了ActionSupport类,因此才会触发这个异常,因此,我选择使用动态代理,具体配置如下:

	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
		<!-- 使用动态代理 -->
		<property name="proxyTargetClass" value="true"></property>
	</bean>
修改好配置文件后,重启项目后,项目依然会报错,而且还是 java.lang.NoSuchMethodException: com.sun.proxy.$Proxy25.test()


经过对配置文件的一翻查看,我发现了在hibernate有关的配置中,我配置了事务切面:

	<aop:config >
		<aop:pointcut id="serviceMethod" expression="execution(* dao.*.*(..))"  />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"  />
	</aop:config>

尝试着将hibernate的切面改为使用动态代理:

	<aop:config proxy-target-class="true">
		<aop:pointcut id="serviceMethod" expression="execution(* dao.*.*(..))"  />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"  />
	</aop:config>

重新启动项目,一切看似都没问题,但是调用使用了shiro注解的action后,即使在shiroFilter中配置了unauthorizedUrl属性,结果依然没有按预想的那样跳转到指定url,而是在页面直接显示出了异常信息,如:

Struts has detected an unhandled exception:

Messages:
  1. Not authorized to invoke method: public java.lang.String action.TestAction.test()
  2. 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. 

下面给出我的解决方案:

在struts.xml中配置异常映射,如:

	<package abstract="true" name="mine" namespace="/" extends="struts-default">
		<global-results>
			<!-- 如果用户没有验证,要跳转的页面 -->
			<result name="unauthorized">/unauthorized.jsp</result>
			<!-- 如果用户没有相应的角色或权限,要跳转的页面 -->
			<result name="unAuthenticated">/login.jsp</result>
		</global-results>
		<global-exception-mappings>
			<!-- 映射没有权限异常 -->
			<exception-mapping result="unauthorized" exception="org.apache.shiro.authz.UnauthorizedException" />
			<!-- 映射没有验证异常 -->
			<exception-mapping result="unAuthenticated" exception="org.apache.shiro.authz.UnauthenticatedException" />
		</global-exception-mappings>
	</package>

注意这里的myPackage为abstract的,也就只中间不能配置action的,但是,我们可以新创建一个package,继承自myPackage,及 extends="myPackage"。


至此,问题基本解决,但是,对于hibernate的事务切面,使用动态代理感觉很不爽,于是,多折腾了会儿,找到了解决办法,下面给出解决方案:

在 org.apache.shiro.spring.security.interceptor  包下有一个 AopAllianceAnnotationsAuthorizingMethodInterceptor  类,因此,可以推测出,可以使用该类进行 aop 配置,配置如下:

    	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
	<aop:config proxy-target-class="true">
    		<aop:pointcut expression="execution(* action.*.*(..))" id="shiroPincut"/>
    		<aop:advisor advice-ref="shiroAdvisor" pointcut-ref="shiroPincut" />
   	</aop:config>
	<bean name="shiroAdvisor" class="org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor" depends-on="lifecycleBeanPostProcessor" />

配置完shiro后,可以将hibernate的切面配置中的 proxy-target-class="true" 属性删除。


至此,shiro注解成功开启!



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值