Spring AOP和apache shiro配置。注释未被扫描

时间:2011-07-28 13:06:16

标签: spring spring-aop shiro

我一直在努力应对需要AOP知识的配置。

我必须承认,AOP是我试图获得一段时间而没有成功的部分。 似乎我的shiro注释没有被扫描,因此被忽略了。

我尝试过使用shiro 1.1.0+ maven3 + spring 3.0.5.RELEASE,hibernate 3.6.1.Final with ZK 5.0.6。 我让我的hibernaterealm工作,与数据库交谈,我认证工作,我成功(我相信)获得角色和权限加载。

所以为了测试授权方,我在我的代码中有一个地方:

  Subject currentUser = SecurityUtils.getSubject();
   if (!currentUser.isPermitted("businessaccount:list")) {
    throw new AuthorizationException("User not authorized");
  }

它工作正常。
所以我知道我的权限已经加载。我将使用注释方便我将它放在实现类中,因为我没有计划在我的控制器类中使用接口来扩展ZK GenericForwardController。 / p>

我已经看到了这个bug,我决定尝试使用@RequiresPersmissions方法的一个接口。

显然它仍然没有工作,因为它可以访问未经授权的主题。我的日志中没有错误。也许我在这里做错了是代码片段:

@Component("layouteventhandler")
public class LayoutEventHandlerImpl extends GenericForwardComposer implements     LayoutEventHandler {

Logger logger = Logger.getLogger(LayoutEventHandlerImpl.class);
Menuitem logout;

//...


@Override
public void onClick$pAccounts() {
    try {
        execution.sendRedirect("/accounts/personal/list");
    } catch (Exception ex) {
        logger.info("Error redirecting to personal accounts", ex);
    }
}


@Override
public void onClick$bAccounts() {
  try {
        execution.sendRedirect("/accounts/business/list");
    } catch (Exception ex) {
        logger.info("Error redirecting to business accounts", ex);
    }
}
//.....
} 

它的界面:

public interface LayoutEventHandler {

@RequiresPermissions(value="personalaccount:list")
public void onClick$pAccounts();

@RequiresPermissions(value="businessaccount:list")
public void onClick$bAccounts();
//.....

 }

这是我的shiro applicationcontext

<bean id="hibernateRealm" class="com.personal.project.admin.webapp.security.DatabaseRealm" />
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="hibernateRealm" />
</bean>

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

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
      depends-on="lifecycleBeanPostProcessor">
 <!--          <property name="proxyTargetClass" value="true" />-->
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
</bean>

<!-- Secure Spring remoting:  Ensure any Spring Remoting method invocations can be associated
     with a Subject for security checks. -->
<bean id="secureRemoteInvocationExecutor" class="org.apache.shiro.spring.remoting.SecureRemoteInvocationExecutor">
    <property name="securityManager" ref="securityManager"/>
</bean>
<!-- ... -->

是否有我应该做的事情?感谢阅读和帮助

3 个答案:

答案 0 :(得分:2)

我不知道Shiro,但我猜你已经在你的bean类上添加了注释来实现接口,然后你将它们代理为安全性,事务和/或其他东西。当发生这种情况时,返回的对象是JDK动态代理,它不是bean的具体类的实例,只是它实现的接口的实例。因此,任何依赖于具体类中的注释的注释扫描都无法找到它们。

答案 1 :(得分:0)

要扩展Ryan Stewart的答案,您需要添加

@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)

到实现类(不是接口)并将Shiro注释移动到它。

答案 2 :(得分:0)

当我运行两个弹簧上下文时,我遇到了类似的问题。有一个父根上下文定义了数据库,服务,安全性和非SpringMVC Web bean以及包含我想要代理的控制器的Spring MVC REST api的子Web上下文。每个上下文的配置是类路径扫描单独的包。

在这种情况下,请确保在子Web上下文中定义了所需的DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor bean(即,Rest控件是类路径扫描的位置),因为在父上下文中定义它们不起作用(文档在事后看来,DefaultAdvisorAutoProxyCreate对此非常清楚!)。

发布此信息以防其他人遇到同样的问题。