Shiro授权使用Annotation无效的权限检查

Fir*_*mir 6 spring shiro

平台:Shiro 1.1.0,Spring 3.0.5

我正在尝试使用Shiro注释来保护MVC Controller方法.但是注释有问题.普通电话正常工作.Shiro调试中也没有具体的内容.

我的shiro配置:

<!-- Security Manager -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="sessionMode" value="native" />
        <property name="realm" ref="jdbcRealm" />
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

    <!-- Caching -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManager" ref="ehCacheManager" />
    </bean>

    <bean id="ehCacheManager"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />

    <bean id="sessionDAO"
        class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO" />

    <bean id="sessionManager"
        class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionDAO" ref="sessionDAO" />
    </bean>


    <!-- JDBC Realm Settings -->
    <bean id="jdbcRealm" class="org.apache.shiro.realm.jdbc.JdbcRealm">
        <property name="name" value="jdbcRealm" />
        <property name="dataSource" ref="dataSource" />
        <property name="authenticationQuery"
            value="SELECT password FROM system_user_accounts WHERE username=? and status=1" />
        <property name="userRolesQuery"
            value="SELECT role_name FROM system_roles r, system_user_accounts u, system_user_roles ur WHERE u.user_id=ur.user_id AND r.role_id=ur.role_id AND u.username=?" />
        <property name="permissionsQuery"
            value="SELECT permission_name FROM system_roles r, system_permissions p, system_role_permission rp WHERE r.role_id=rp.role_id AND p.permission_id=rp.permission_id AND r.role_name=?" />
        <property name="permissionsLookupEnabled" value="true"></property>
    </bean>

    <!-- Spring Integration -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

    <!-- Enable Shiro Annotations for Spring-configured beans. Only run after 
        the lifecycleBeanProcessor has run: -->
    <bean id="annotationProxy"
        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>

    <!-- 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>

    <!-- Shiro filter -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/login" />
        <property name="successUrl" value="/dashboard" />
        <property name="unauthorizedUrl" value="/error" />
        <property name="filterChainDefinitions">
            <value> 
                <!-- !!! Order matters !!! -->
                /authenticate = anon
                /login = anon
                /logout = anon
                /error = anon
                /** = authc
            </value>
        </property>
    </bean>
Run Code Online (Sandbox Code Playgroud)

我可以正常工作:

@RequestMapping(value="/form") 
public String viewPatientForm(Model model, @RequestParam(value="patientId", required=false) Long patientId){    
   if (!SecurityUtils.getSubject().isPermitted("hc:viewPatient")){
      logger.error("Operation not permitted");
      throw new AuthorizationException("No Permission"); 
   }
}
Run Code Online (Sandbox Code Playgroud)

但以下不起作用:

@RequiresPermissions("hc:patientView")
    @RequestMapping(value="/form")
    public String viewPatientForm(Model model, @RequestParam(value="patientId", required=false) Long patientId){    
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?请帮忙.

小智 9

你是对的.看到你的评论后,我开始考虑一下.那么我发现它不是Shiro的实现问题,但是jar依赖没有正确配置.Shiro的pom.xml也应该依赖于cglib2.

所以下面的修改对我有用:

  1. 包括所有这四个jar文件.

    aspectjrt-1.6.11.jar,
    aspectjweaver-1.6.12.jar,
    cglib-2.2.2.jar,
    asm-3.3.1.jar,

如果您正在使用maven,那么:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.11</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.12</version>
</dependency>    
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

最后将aop:aspectj-autoproxy放在webApplicationContext.xml中

<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- Annotation, so that it's easier to search controllers/components -->
<context:component-scan base-package="com.pepsey.soft.web.controller"/>
Run Code Online (Sandbox Code Playgroud)

注意:上述两个配置应放在同一个spring-webApplicationContext.xml中.否则它将无法工作.此外,如果您在配置中使用了它,则删除context:annotation-config.上下文:组件扫描已扫描所有注释.

一旦开始测试,将log4j设置为debug或(更好)跟踪模式.无论何时启动服务器,您都会在日志中找到以下条目:

08:16:24,684 DEBUG AnnotationAwareAspectJAutoProxyCreator:537 - 使用0个公共拦截器和1个特定拦截器为bean'userController'创建隐式代理