Shiro的注解授权不起作用

这是我的controller

package com.ivo.controller;



import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.ivo.model.User;
import com.ivo.service.UserService;

@Controller
@RequestMapping(value="/user")
public class LoginController {
    @Resource(name="userService")
    private UserService userService;
    @RequestMapping(value="/check")
    public String findUser(User user){
        Subject subject = SecurityUtils.getSubject();
        System.out.println("权限:"+subject.isPermitted("Q8"));
//      Session session = subject.getSession();
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserid(),user.getPassword());
            token.setRememberMe(true);
            try {
                subject.login(token);//跳到realm
//              session.setTimeout(100);
                return "main";
            }catch (AuthenticationException e) {
                token.clear();  
                return "register";
            }

    }
    @RequestMapping(value="/register")
    public String register(){
        return "register";
    }

    @RequiresPermissions("Q8")
    @RequestMapping(value="/master")        //注解授权在这里
    public String master(){
        return "master";
    }
    @RequestMapping(value="/logout")
    public String exit(){

        Subject subject = SecurityUtils.getSubject();
        System.out.println("SessionID:"+subject.getSession().getId());
        if(subject.getSession()==null){
            System.out.println("没有Session");
        }else{
            System.out.println("有Session");
        }
        SecurityUtils.getSubject().logout();
        return "register";
    }
}

下面是我的applicationContent.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
                        http://www.springframework.org/schema/mvc 
                        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                        http://www.springframework.org/schema/aop 
                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
                        http://www.springframework.org/schema/tx 
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">

    <!-- 注解驱动 -->
    <context:component-scan base-package="com.ivo"></context:component-scan>
    <context:component-scan base-package="com.ivo.controller"></context:component-scan>
    <tx:annotation-driven proxy-target-class="true"/>
    <mvc:annotation-driven />
    <!-- 组件扫描 -->
    <!-- 启动组件扫描,排除@Controller组件,该组件由SpringMVC配置文件扫描 -->
    <!-- 定义数据源 -->
    <!-- c3p0有自动回收空闲连接功能 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="" />
        <property name="user" value="root" />
        <property name="password" value="root" />

        <property name="initialPoolSize" value="10" />
        <property name="maxPoolSize" value="50" />
        <property name="minPoolSize" value="10" />
    </bean>

    <bean id="sf" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>

        <!-- hibernate映射文件的位置 -->
        <property name="mappingDirectoryLocations">
            <value>classpath:com/ivo/model/</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.Dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl">update</prop>
            </props>
        </property>
    </bean>

    <!-- 事务管理器 -->
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sf"></property>
    </bean>
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myDbRealm" />
        <property name="sessionManager" ref="sessionManager" />
    </bean>
    <bean id=" myDbRealm" class="com.ivo.realm.MyDbRealm" />
    <!-- Shiro Filter -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- shiro的核心安全接口 -->
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/" />
        <!-- 登陆成功后要跳转的连接 -->
        <property name="successUrl" value="/success" />
        <!-- 没有权限要跳转的链接 -->
        <property name="unauthorizedUrl" value="/regester" />
        <!-- 默认的连接拦截配置 -->
        <!-- <property name="filterChainDefinitions"> 
        </property> -->
    </bean>
    <bean id="sessionDAO" class="com.ivo.dao.MySessionDao"></bean>
    <bean id="sessionListener" class="com.ivo.dao.MyListener"></bean>
    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionValidationSchedulerEnabled" value="false" />
        <property name="sessionDAO" ref="sessionDAO" />
        <property name="sessionListeners" ref="sessionListener" />
        <property name="globalSessionTimeout" value="90000" />
    </bean>

    <!-- 配置事物的传播特性 (事物通知) -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!-- REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启 -->
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="find*" read-only="true" />
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:advisor pointcut="execution(* com.ivo.service.*.*(..))" advice-ref="txAdvice" />
    </aop:config>
</beans>

当我运行项目的时候没有报错,原本的意思是只有Q8权限的subject可以打开,但是实际情况是没有这个权限的subject也可以打开,相当困惑,这是什么原因导致的呢?希望大家能帮忙给看看,先在这里谢过了~

阅读 20.7k
2 个回答

我通过对比github上面的sample发现原来是applicationContext.xml中不扫描Controller,而将其放在springmvc.xml中扫描就OK了。

以下是applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
                        http://www.springframework.org/schema/mvc 
                        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                        http://www.springframework.org/schema/aop 
                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
                        http://www.springframework.org/schema/tx 
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">

    <!-- Enable annotation configuration -->
    <context:annotation-config/>
    <!-- Scan sample packages for Spring annotations -->
    <context:component-scan base-package="com.ivo.dao"/>
    <context:component-scan base-package="com.ivo.realm"/>
    <context:component-scan base-package="com.ivo.service"/>
     <!-- Spring AOP auto-proxy creation (required to support Shiro annotations) -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://10.20.2.9/springmvc" />
        <property name="user" value="root" />
        <property name="password" value="root" />

        <property name="initialPoolSize" value="10" />
        <property name="maxPoolSize" value="50" />
        <property name="minPoolSize" value="10" />
    </bean>

        <!-- Hibernate SessionFactory -->
    <bean id="sf" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <!-- hibernate映射文件的位置 -->
        <property name="mappingDirectoryLocations">
            <value>classpath:com/ivo/model/</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.Dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl">update</prop>
            </props>
        </property>
    </bean>
     <!-- Transaction support beans -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sf"/>
    </bean>

    <tx:annotation-driven/>
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myDbRealm" />
        <property name="sessionManager" ref="sessionManager" />
    </bean>
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
        <!-- Shiro Filter -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- shiro的核心安全接口 -->
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/" />
        <!-- 登陆成功后要跳转的连接 -->
        <property name="successUrl" value="/success" />
        <!-- 没有权限要跳转的链接 -->
        <property name="unauthorizedUrl" value="/regester" />
        <!-- 默认的连接拦截配置 -->
    <!--    <property name="filterChainDefinitions">
            <value>
            /user/master = perms[permission:Q6]
            </value> 
        </property> -->
    </bean>
    <bean id="sessionDAO" class="com.ivo.dao.MySessionDao"></bean>
    <bean id="sessionListener" class="com.ivo.dao.MyListener"></bean>
    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionValidationSchedulerEnabled" value="false" />
        <property name="sessionDAO" ref="sessionDAO" />
        <property name="sessionListeners" ref="sessionListener" />
        <property name="globalSessionTimeout" value="90000" />
    </bean>
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sf"></property>
    </bean>
    <bean id=" myDbRealm" class="com.ivo.realm.MyDbRealm" />
    <!-- 配置事物的传播特性 (事物通知) -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!-- REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启 -->
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="find*" read-only="true" />
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:advisor pointcut="execution(* com.ivo.*.*.*(..))" advice-ref="txAdvice" />
    </aop:config> 
</beans>

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
                        http://www.springframework.org/schema/mvc 
                        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                        http://www.springframework.org/schema/aop 
                        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
                        http://www.springframework.org/schema/tx 
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">


 <!-- Enable annotation component scanning and autowiring of web package -->
    <context:annotation-config/>
    <context:component-scan base-package="com.ivo.controller"/>

    <!-- Required for security annotations to work in this servlet -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>


    <!-- Enable annotation-based controllers using @Controller annotations -->
    <bean id="annotationUrlMapping"  class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    </bean>

    <bean id="annotationMethodHandlerAdapter"
          class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>                       




    <!-- <context:component-scan base-package="org.shiro.demo.controller" /> -->
    <!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> -->
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 /WEB-INF/jsps/home.jsp-->
        <property name="prefix" value="/WEB-INF/jsps/"></property>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

困扰了我好几天,终于搞定了!

感谢,解决了!要是能把原理加上就完美啦!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏