SpringMVC+shiro+hibernate权限管理整合

什么是权限?

权限是管理web应用用户的一种手段,比如,一个电商平台,用户具有user的角色,他可以在这个商场里面进行交易。商家拥有的是user的角色同时也拥有manager的角色,因此,他可以进行买卖的同时进行对自己商品的管理。shiro就是一个基于RBAC权限设计模型的权限管理框架。

什么是Shiro ?

Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能: 
认证 - 用户身份识别,常被称为用户“登录”;
授权 - 访问控制;
密码加密 - 保护或隐藏数据防止被偷窥;
会话管理 - 每用户相关的时间敏感的状态。

以下是对使用SpringMVC+shiro+hibernate框架对用户管理的一个例子:

附上项目:https://git.oschina.net/jeremie_astray/SpringMVC_Shiro/tree/master/

Annotion版本:https://git.oschina.net/jeremie_astray/SpringMVC_Shiro/tree/shiro_annotation

一、实体


对应关系:

用户与角色为一对多关系

角色与权限为多对多关系

权限过滤与角色和权限为一对一关系

 

t_user(,用户表,密码为md5加密,可以自己修改)


t_role(角色表)


t_permission(权限表)


t_function(权限过滤表)


t_user_role(用户-角色表中间表)


t_role_permission(角色-权限表,中间表)


 

实体类可以在文章结尾的git链接查看

二、包导入及spring配置

maven配置如下:

[html]   view plain  copy
  1. <span style="font-size:12px;">    <properties>  
  2.         <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>  
  3.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  4.         <spring.version>4.1.0.RELEASE</spring.version>  
  5.     </properties>  
  6.       
  7.     <dependencies>  
  8.         <dependency>  
  9.             <groupId>junit</groupId>  
  10.             <artifactId>junit</artifactId>  
  11.             <version>3.8.1</version>  
  12.             <scope>test</scope>  
  13.         </dependency>  
  14.         <!-- SpringMVCjar -->  
  15.         <dependency>  
  16.             <groupId>org.springframework</groupId>  
  17.             <artifactId>spring-aspects</artifactId>  
  18.             <version>${spring.version}</version>  
  19.         </dependency>  
  20.         <dependency>  
  21.             <groupId>org.springframework</groupId>  
  22.             <artifactId>spring-beans</artifactId>  
  23.             <version>${spring.version}</version>  
  24.         </dependency>  
  25.         <dependency>  
  26.             <groupId>org.springframework</groupId>  
  27.             <artifactId>spring-context</artifactId>  
  28.             <version>${spring.version}</version>  
  29.         </dependency>  
  30.         <dependency>  
  31.             <groupId>org.springframework</groupId>  
  32.             <artifactId>spring-context-support</artifactId>  
  33.             <version>${spring.version}</version>  
  34.         </dependency>  
  35.         <dependency>  
  36.             <groupId>org.springframework</groupId>  
  37.             <artifactId>spring-core</artifactId>  
  38.             <version>${spring.version}</version>  
  39.         </dependency>  
  40.         <dependency>  
  41.             <groupId>org.springframework</groupId>  
  42.             <artifactId>spring-expression</artifactId>  
  43.             <version>${spring.version}</version>  
  44.         </dependency>  
  45.         <dependency>  
  46.             <groupId>org.springframework</groupId>  
  47.             <artifactId>spring-jdbc</artifactId>  
  48.             <version>${spring.version}</version>  
  49.         </dependency>  
  50.         <dependency>  
  51.             <groupId>org.springframework</groupId>  
  52.             <artifactId>spring-orm</artifactId>  
  53.             <version>${spring.version}</version>  
  54.         </dependency>  
  55.         <dependency>  
  56.             <groupId>org.springframework</groupId>  
  57.             <artifactId>spring-tx</artifactId>  
  58.             <version>${spring.version}</version>  
  59.         </dependency>  
  60.         <dependency>  
  61.             <groupId>org.springframework</groupId>  
  62.             <artifactId>spring-web</artifactId>  
  63.             <version>${spring.version}</version>  
  64.         </dependency>  
  65.         <dependency>  
  66.             <groupId>org.springframework</groupId>  
  67.             <artifactId>spring-webmvc</artifactId>  
  68.             <version>${spring.version}</version>  
  69.         </dependency>  
  70.         <dependency>  
  71.             <groupId>org.springframework</groupId>  
  72.             <artifactId>spring-test</artifactId>  
  73.             <version>${spring.version}</version>  
  74.             <scope>test</scope>  
  75.         </dependency>  
  76.         <!-- Hibernate-->  
  77.         <dependency>  
  78.             <groupId>net.sf.ehcache</groupId>  
  79.             <artifactId>ehcache</artifactId>  
  80.             <version>2.7.2</version>  
  81.         </dependency>  
  82.         <dependency>  
  83.             <groupId>commons-dbcp</groupId>  
  84.             <artifactId>commons-dbcp</artifactId>  
  85.             <version>1.4</version>  
  86.         </dependency>  
  87.         <dependency>  
  88.             <groupId>mysql</groupId>  
  89.             <artifactId>mysql-connector-java</artifactId>  
  90.             <version>5.1.26</version>  
  91.         </dependency>  
  92.         <!-- javax提供的annotation -->  
  93.         <dependency>  
  94.             <groupId>javax.inject</groupId>  
  95.             <artifactId>javax.inject</artifactId>  
  96.             <version>1</version>  
  97.         </dependency>  
  98.         <!-- **************************** -->  
  99.   
  100.         <!-- hibernate验证 -->  
  101.         <dependency>  
  102.             <groupId>org.hibernate</groupId>  
  103.             <artifactId>hibernate-core</artifactId>  
  104.             <version>4.3.6.Final</version>  
  105.         </dependency>  
  106.         <dependency>  
  107.             <groupId>org.hibernate.common</groupId>  
  108.             <artifactId>hibernate-commons-annotations</artifactId>  
  109.             <version>4.0.5.Final</version>  
  110.         </dependency>  
  111.         <dependency>  
  112.             <groupId>org.hibernate</groupId>  
  113.             <artifactId>hibernate-entitymanager</artifactId>  
  114.             <version>4.3.6.Final</version>  
  115.         </dependency>  
  116.         <dependency>  
  117.             <groupId>org.hibernate.javax.persistence</groupId>  
  118.             <artifactId>hibernate-jpa-2.1-api</artifactId>  
  119.             <version>1.0.0.Final</version>  
  120.         </dependency>  
  121.         <dependency>  
  122.             <groupId>org.hibernate</groupId>  
  123.             <artifactId>hibernate-ehcache</artifactId>  
  124.             <version>4.3.6.Final</version>  
  125.         </dependency>  
  126.         <dependency>  
  127.             <groupId>org.hibernate</groupId>  
  128.             <artifactId>hibernate-validator</artifactId>  
  129.             <version>5.1.2.Final</version>  
  130.         </dependency>  
  131.         <dependency>  
  132.             <groupId>com.mchange</groupId>  
  133.             <artifactId>c3p0</artifactId>  
  134.             <version>0.9.5-pre8</version>  
  135.         </dependency>  
  136.         <!-- jstl -->  
  137.         <dependency>  
  138.             <groupId>javax.servlet</groupId>  
  139.             <artifactId>jstl</artifactId>  
  140.             <version>1.2</version>  
  141.         </dependency>  
  142.         <!-- servlet -->  
  143.         <dependency>  
  144.             <groupId>javax.servlet</groupId>  
  145.             <artifactId>javax.servlet-api</artifactId>  
  146.             <version>3.1.0</version>  
  147.             <scope>provided</scope>  
  148.         </dependency>  
  149.         <dependency>  
  150.             <groupId>javax.servlet.jsp</groupId>  
  151.             <artifactId>javax.servlet.jsp-api</artifactId>  
  152.             <version>2.3.1</version>  
  153.             <scope>provided</scope>  
  154.         </dependency>  
  155.         <!-- Shiro -->  
  156.         <dependency>  
  157.             <groupId>org.apache.shiro</groupId>  
  158.             <artifactId>shiro-core</artifactId>  
  159.             <version>1.2.3</version>  
  160.         </dependency>  
  161.         <dependency>  
  162.             <groupId>org.apache.shiro</groupId>  
  163.             <artifactId>shiro-web</artifactId>  
  164.             <version>1.2.3</version>  
  165.         </dependency>  
  166.         <dependency>  
  167.             <groupId>org.apache.shiro</groupId>  
  168.             <artifactId>shiro-spring</artifactId>  
  169.             <version>1.2.3</version>  
  170.         </dependency>  
  171.         <dependency>  
  172.             <groupId>org.apache.shiro</groupId>  
  173.             <artifactId>shiro-ehcache</artifactId>  
  174.             <version>1.2.3</version>  
  175.         </dependency>  
  176.         <dependency>  
  177.             <groupId>commons-io</groupId>  
  178.             <artifactId>commons-io</artifactId>  
  179.             <version>2.4</version>  
  180.         </dependency>  
  181.         <dependency>  
  182.             <groupId>commons-beanutils</groupId>  
  183.             <artifactId>commons-beanutils</artifactId>  
  184.             <version>1.8.3</version>  
  185.         </dependency>  
  186.         <dependency>  
  187.             <groupId>commons-fileupload</groupId>  
  188.             <artifactId>commons-fileupload</artifactId>  
  189.             <version>1.3.1</version>  
  190.         </dependency>  
  191.         <dependency>  
  192.             <groupId>commons-lang</groupId>  
  193.             <artifactId>commons-lang</artifactId>  
  194.             <version>2.6</version>  
  195.         </dependency>  
  196.         <dependency>  
  197.             <groupId>commons-logging</groupId>  
  198.             <artifactId>commons-logging</artifactId>  
  199.             <version>1.1.2</version>  
  200.         </dependency>  
  201.         <dependency>  
  202.             <groupId>org.slf4j</groupId>  
  203.             <artifactId>slf4j-log4j12</artifactId>  
  204.             <version>1.7.5</version>  
  205.         </dependency>  
  206.         <dependency>  
  207.             <groupId>asm</groupId>  
  208.             <artifactId>asm</artifactId>  
  209.             <version>3.3.1</version>  
  210.         </dependency>  
  211.         <dependency>  
  212.             <groupId>org.aspectj</groupId >  
  213.             <artifactId>aspectjweaver</artifactId >  
  214.             <version> 1.6.11</version >  
  215.         </dependency>  
  216.     </dependencies>  
  217.   
  218.     <build>  
  219.         <plugins>  
  220.             <plugin>  
  221.                 <groupId>org.apache.maven.plugins</groupId>  
  222.                 <artifactId>maven-compiler-plugin</artifactId>  
  223.                 <version>3.1</version>  
  224.                 <configuration>  
  225.                     <source>1.7</source>  
  226.                     <target>1.7</target>  
  227.                     <encoding>UTF8</encoding>  
  228.                     <compilerArguments>  
  229.                         <endorseddirs>${endorsed.dir}</endorseddirs>  
  230.                     </compilerArguments>  
  231.                 </configuration>  
  232.             </plugin>  
  233.             <plugin>  
  234.                 <groupId>org.apache.maven.plugins</groupId>  
  235.                 <artifactId>maven-war-plugin</artifactId>  
  236.                 <version>2.4</version>  
  237.                 <configuration>  
  238.                     <failOnMissingWebXml>false</failOnMissingWebXml>  
  239.                 </configuration>  
  240.             </plugin>  
  241.             <!-- tomcat7maven插件 -->  
  242.             <plugin>  
  243.                 <groupId>org.apache.tomcat.maven</groupId>  
  244.                 <artifactId>tomcat7-maven-plugin</artifactId>  
  245.                 <version>2.2</version>  
  246.                 <configuration>  
  247.                     <path>/</path>  
  248.                     <port>80</port>  
  249.                     <contextReloadable>true</contextReloadable>  
  250.                     <contextFile>src/main/webapp/META-INF/context.xml</contextFile>  
  251.                 </configuration>  
  252.             </plugin>  
  253.             <plugin>  
  254.                 <groupId>org.apache.maven.plugins</groupId>  
  255.                 <artifactId>maven-dependency-plugin</artifactId>  
  256.                 <version>2.6</version>  
  257.                 <executions>  
  258.                     <execution>  
  259.                         <phase>validate</phase>  
  260.                         <goals>  
  261.                             <goal>copy</goal>  
  262.                         </goals>  
  263.                         <configuration>  
  264.                             <outputDirectory>${endorsed.dir}</outputDirectory>  
  265.                             <silent>true</silent>  
  266.                             <artifactItems>  
  267.                                 <artifactItem>  
  268.                                     <groupId>javax</groupId>  
  269.                                     <artifactId>javaee-endorsed-api</artifactId>  
  270.                                     <version>7.0</version>  
  271.                                     <type>jar</type>  
  272.                                 </artifactItem>  
  273.                             </artifactItems>  
  274.                         </configuration>  
  275.                     </execution>  
  276.                 </executions>  
  277.             </plugin>  
  278.         </plugins>  
  279.     </build></span>  

备注:maven的tomcat7插件可以使用tomcat7:run指令运行

 

web.xml的配置
[html]   view plain  copy
  1. <span style="font-size:12px;"><?xml version="1.0" encoding="UTF-8" ?>  
  2. <web-app version="2.5"  
  3.          xmlns="http://java.sun.com/xml/ns/javaee"  
  4.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  7.     <display-name>Archetype Created Web Application</display-name>  
  8.   
  9.   
  10.     <!--过滤字符集-->  
  11.     <filter>  
  12.         <filter-name>encoding</filter-name>  
  13.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
  14.         <init-param>  
  15.             <param-name>encoding</param-name>  
  16.             <param-value>UTF-8</param-value>  
  17.         </init-param>  
  18.     </filter>  
  19.     <filter-mapping>  
  20.         <filter-name>encoding</filter-name>  
  21.         <url-pattern>/*</url-pattern>  
  22.     </filter-mapping>  
  23.     <!-- spring-orm-hibernate4的OpenSessionInViewFilter -->  
  24.     <filter>  
  25.         <filter-name>opensessioninview</filter-name>  
  26.         <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>  
  27.     </filter>  
  28.     <filter-mapping>  
  29.         <filter-name>opensessioninview</filter-name>  
  30.         <url-pattern>/*</url-pattern>  
  31.     </filter-mapping>  
  32.   
  33.     <!-- 配置springmvc servlet -->  
  34.     <servlet>  
  35.         <servlet-name>springmvc</servlet-name>  
  36.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  37.         <load-on-startup>1</load-on-startup>  
  38.     </servlet>  
  39.     <servlet-mapping>  
  40.         <servlet-name>springmvc</servlet-name>  
  41.         <!-- / 表示所有的请求都要经过此serlvet -->  
  42.         <url-pattern>*.html</url-pattern>  
  43.     </servlet-mapping>  
  44.   
  45.     <!-- spring的监听器 -->  
  46.     <context-param>  
  47.         <param-name>contextConfigLocation</param-name>  
  48.         <param-value>classpath*:applicationContext.xml</param-value>  
  49.     </context-param>  
  50.     <listener>  
  51.         <listener-class>  
  52.             org.springframework.web.context.ContextLoaderListener  
  53.         </listener-class>  
  54.     </listener>  
  55.   
  56.     <!-- Shiro配置 -->  
  57.     <filter>  
  58.         <filter-name>shiroFilter</filter-name>  
  59.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  60.     </filter>  
  61.     <filter-mapping>  
  62.         <filter-name>shiroFilter</filter-name>  
  63.         <url-pattern>/*</url-pattern>  
  64.     </filter-mapping>  
  65.   
  66.     <welcome-file-list>  
  67.         <welcome-file>login.html</welcome-file>  
  68.     </welcome-file-list>  
  69. </web-app>  </span>  

备注:springmvc只对*.html进行过滤,而shiro则是对所有url进行过滤

springmvc-servlet的配置

[html]   view plain  copy
  1. <span style="font-size:12px;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.         http://www.springframework.org/schema/beans/spring-beans.xsd  
  8.         http://www.springframework.org/schema/context  
  9.         http://www.springframework.org/schema/context/spring-context.xsd  
  10.         http://www.springframework.org/schema/mvc   
  11.         http://www.springframework.org/schema/mvc/spring-mvc.xsd">  
  12.     <context:component-scan base-package="com.etop" use-default-filters="false">  
  13.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
  14.     </context:component-scan>  
  15.     <context:component-scan base-package="com.etop.controller"/>  
  16.     <mvc:annotation-driven/>  
  17.     <!-- 根据客户端的不同的请求决定不同的view进行响应, 如 /blog/1.json /blog/1.xml -->  
  18.     <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">  
  19.         <!-- 扩展名至mimeType的映射,即 /account.json => application/json -->  
  20.         <property name="favorPathExtension" value="true"/>  
  21.         <!-- 用于开启 /userinfo/123?format=json 的支持 -->  
  22.         <property name="favorParameter" value="true"/>  
  23.         <property name="parameterName" value="format"/>  
  24.         <!-- 是否忽略Accept Header -->  
  25.         <property name="ignoreAcceptHeader" value="false"/>  
  26.         <property name="mediaTypes"> <!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->  
  27.             <value>  
  28.                 ccjson=application/json  
  29.                 ccxml=application/xml  
  30.                 html=text/html  
  31.             </value>  
  32.         </property>  
  33.         <!-- 默认的content type -->  
  34.         <property name="defaultContentType" value="text/html"/>  
  35.     </bean>  
  36. </beans></span>  
applicationContext.xml的配置
[html]   view plain  copy
  1. <span style="font-size:12px;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:aop="http://www.springframework.org/schema/aop"  
  5.        xmlns:context="http://www.springframework.org/schema/context"  
  6.        xmlns:tx="http://www.springframework.org/schema/tx"  
  7.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  8.           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  
  9.           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd  
  10.           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd  
  11. default-lazy-init="true">  
  12.   
  13.   
  14.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  15.         <property name="realm" ref="myRealm"/>  
  16.         <!-- 使用下面配置的缓存管理器 -->  
  17.         <property name="cacheManager" ref="cacheManager"/>  
  18.     </bean>  
  19.     <!--自定义Realm-->  
  20.     <bean id="myRealm" class="com.etop.shiro.MyRealm"/>  
  21.   
  22.     <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->  
  23.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  24.         <!-- 调用我们配置的权限管理器 -->  
  25.         <property name="securityManager" ref="securityManager"/>  
  26.         <!-- 配置我们的登录请求地址 -->  
  27.         <property name="loginUrl" value="/login.html"/>  
  28.         <!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 -->  
  29.         <property name="successUrl" value="/user.html"/>  
  30.         <!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 -->  
  31.         <property name="unauthorizedUrl" value="/403.html"/>  
  32.         <!-- 权限配置 -->  
  33.         <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource"/>  
  34.     </bean>  
  35.     <!--自定义filterChainDefinitionMap-->  
  36.     <bean id="chainDefinitionSectionMetaSource" class="com.etop.shiro.ChainDefinitionSectionMetaSource"/>  
  37.     <!--shiro缓存管理器-->  
  38.     <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>  
  39.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  40.   
  41.   
  42.     <bean id="propertyConfigurer"  
  43.           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  44.         <property name="locations" value="classpath:jdbc.properties"/>  
  45.     </bean>  
  46.   
  47.     <!--hibernate session工厂设置-->  
  48.     <bean id="sessionFactory"  
  49.           class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
  50.         <property name="dataSource" ref="dataSource"/>  
  51.         <property name="packagesToScan">  
  52.             <list>  
  53.                 <value>com.etop.pojo</value>  
  54.             </list>  
  55.         </property>  
  56.         <property name="hibernateProperties">  
  57.             <props>  
  58.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>  
  59.                 <prop key="hibernate.generate_statistics">false</prop>  
  60.                 <prop key="hibernate.show_sql">true</prop>  
  61.                 <prop key="hibernate.format_sql">false</prop>  
  62.                 <prop key="hibernate.jdbc.batch_size">50</prop>  
  63.                 <prop key="jdbc.use_scrollable_resultset">false</prop>  
  64.                 <prop key="javax.persistence.validation.mode">none</prop>  
  65.                 <prop key="hibernate.cache.use_second_level_cache">true</prop>  
  66.                 <prop key="hibernate.cache.use_query_cache">true</prop>  
  67.                 <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>  
  68.                 <prop key="jdbc.use_scrollable_resultset">false</prop>  
  69.             </props>  
  70.         </property>  
  71.     </bean>  
  72.   
  73.     <!-- c3p0 configuration -->  
  74.     <bean id="mainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
  75.         <property name="driverClass" value="${jdbc.driverClass}"/>  
  76.         <property name="jdbcUrl" value="${jdbc.url}"/>  
  77.         <property name="user" value="${jdbc.username}"/>  
  78.         <property name="password" value="${jdbc.password}"/>  
  79.         <property name="minPoolSize" value="${jdbc.minPoolSize}"/>  
  80.         <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>  
  81.         <property name="checkoutTimeout" value="${jdbc.checkoutTimeout}"/>  
  82.         <property name="maxStatements" value="${jdbc.maxStatements}"/>  
  83.         <property name="testConnectionOnCheckin" value="${jdbc.testConnectionOnCheckin}"/>  
  84.         <property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}"/>  
  85.     </bean>  
  86.   
  87.     <bean id="dataSource"  
  88.           class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">  
  89.         <property name="targetDataSource">  
  90.             <ref bean="mainDataSource"/>  
  91.         </property>  
  92.     </bean>  
  93.     <context:annotation-config/>  
  94.     <context:component-scan base-package="com.etop">  
  95.         <context:exclude-filter type="regex" expression="com.cn.controller.*"/>  
  96.     </context:component-scan>  
  97.   
  98.     <bean id="transactionManager"  
  99.           class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
  100.         <property name="sessionFactory">  
  101.             <ref bean="sessionFactory"/>  
  102.         </property>  
  103.     </bean>  
  104.   
  105.     <!-- 拦截配置 -->  
  106.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  107.         <tx:attributes>  
  108.             <!--说明事务类别 -->  
  109.             <tx:method name="delete*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
  110.             <tx:method name="save*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
  111.             <tx:method name="add*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
  112.             <tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
  113.             <tx:method name="batch*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
  114.             <tx:method name="sendOpen*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
  115.             <tx:method name="sendClose*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>  
  116.             <tx:method name="find*" propagation="REQUIRED" read-only="true"/>  
  117.             <tx:method name="get*" propagation="REQUIRED" read-only="true"/>  
  118.             <tx:method name="load*" propagation="REQUIRED" read-only="true"/>  
  119.             <tx:method name="*" read-only="true"/>  
  120.         </tx:attributes>  
  121.     </tx:advice>  
  122.   
  123.     <!-- 切入点 -->  
  124.     <aop:config expose-proxy="true" proxy-target-class="true">  
  125.         <!-- service层事务 -->  
  126.         <aop:advisor id="serviceTx" advice-ref="txAdvice"  
  127.                      pointcut="execution(public * com.etop.service.*.*(..))" order="1"/>  
  128.     </aop:config>  
  129.   
  130.     <tx:annotation-driven/>  
  131.   
  132. </beans>  
  133. </span>  

备注:配置好自定义的Realm与chainDefinitionSectionMetaSource

  • securityManager是shiro的核心,初始化时协调各个模块运行。
  • realm是shiro的桥梁,进行数据源配置

jdbc.properties:

[java]   view plain  copy
  1. <span style="font-size:12px;">jdbc.driverClass = com.mysql.jdbc.Driver  
  2. jdbc.url = jdbc:mysql://127.0.0.1:3306/shiro  
  3. jdbc.username = root  
  4. jdbc.password = root  
  5. jdbc.minPoolSize=2  
  6. jdbc.maxPoolSize=20  
  7. jdbc.checkoutTimeout=3000  
  8. jdbc.maxStatements=50  
  9. jdbc.testConnectionOnCheckin = false  
  10. jdbc.idleConnectionTestPeriod = 18000</span>  
三、自定义Realm及自定义filterChainDefinition

Realm是shiro获取身份验证相关信息与获取授权信息的重写:

获取授权信息(doGetAuthorizationInfo())通过用户名和userService接口就可以获取对应角色及权限信息。

获取身份验证相关信息(doGetAuthenticationInfo()):首先根据传入的用户名获取User信息;然后如果user为空,那么抛出没找到帐号异常UnknownAccountException;如果user找到但锁定了抛出锁定异常LockedAccountException;最后生成AuthenticationInfo信息,交给间接父类AuthenticatingRealm使用CredentialsMatcher进行判断密码是否匹配,如果不匹配将抛出密码错误异常IncorrectCredentialsException;另外如果密码重试此处太多将抛出超出重试次数异常ExcessiveAttemptsException;

而filterChainDefinition则是对url访问权限的重写:

产生责任链,确定每个url的访问权限

参见格式如下:

/static/**=anon  
<!-- perms[user:query]表示访问此连接需要权限为user:query的用户 -->  
/user=perms[user:query]  
<!-- roles[manager]表示访问此连接需要用户的角色为manager -->  
/user/add=roles[manager]  
/user/del/**=roles[admin]  
/user/edit/**=roles[manager]

原本是由ini文件直接读取,我这里写成由数据库读取,方便管理

MyRealm.java

[java]   view plain  copy
  1. <span style="font-size:12px;">package com.etop.shiro;  
  2.   
  3. import java.util.Collection;  
  4.   
  5. import javax.inject.Inject;  
  6.   
  7. import com.etop.service.UserService;  
  8. import org.apache.shiro.authc.AuthenticationException;  
  9. import org.apache.shiro.authc.AuthenticationInfo;  
  10. import org.apache.shiro.authc.AuthenticationToken;  
  11. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  12. import org.apache.shiro.authc.UsernamePasswordToken;  
  13. import org.apache.shiro.authz.AuthorizationInfo;  
  14. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  15. import org.apache.shiro.realm.AuthorizingRealm;  
  16. import org.apache.shiro.subject.PrincipalCollection;  
  17. import org.springframework.stereotype.Service;  
  18. import org.springframework.transaction.annotation.Transactional;  
  19.   
  20. import com.etop.pojo.Role;  
  21. import com.etop.pojo.User;  
  22.   
  23. /** 
  24.  * Created by Jeremie on 2014/10/1. 
  25.  */  
  26.   
  27. @Service  
  28. @Transactional  
  29. public class MyRealm extends AuthorizingRealm{  
  30.   
  31.     @Inject  
  32.     private UserService userService;  
  33.     /** 
  34.      * <span style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px;"><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px;">获取授权信息</span></span> 
  35.      */  
  36.     @Override  
  37.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {  
  38.         //获取登录时输入的用户名    
  39.         String loginName=(String) principalCollection.fromRealm(getName()).iterator().next();  
  40.         //到数据库获取此用户  
  41.         User user=userService.findByName(loginName);  
  42.         if(user!=null){  
  43.             //权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)    
  44.             SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();  
  45.             //用户的角色集合  
  46.             info.setRoles(user.getRolesName());  
  47.             //用户的角色对应的所有权限,如果只使用角色定义访问权限  
  48.             Collection<Role> roleList=user.getRoleList();  
  49.             for (Role role : roleList) {  
  50.                 info.addStringPermissions(role.getPermissionsName());  
  51.             }  
  52.             return info;  
  53.         }  
  54.         return null;  
  55.     }  
  56.   
  57.     /** 
  58.      * 获取身份验证相关信息 
  59.      */  
  60.     @Override  
  61.     protected AuthenticationInfo doGetAuthenticationInfo(  
  62.             AuthenticationToken authenticationToken) throws AuthenticationException {  
  63.         //UsernamePasswordToken对象用来存放提交的登录信息    
  64.         UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;  
  65.         //查出是否有此用户    
  66.         User user=userService.findByName(token.getUsername());  
  67.         if(user!=null){  
  68.             //若存在,将此用户存放到登录认证info中    
  69.             return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());  
  70.         }  
  71.         return null;  
  72.     }  
  73.   
  74. }</span>  

ChainDefinitionSectionMetaSource.java
[java]   view plain  copy
  1. <span style="font-size:12px;">package com.etop.shiro;  
  2.   
  3. import com.etop.pojo.Function;  
  4. import com.etop.service.FunctionService;  
  5. import org.apache.commons.lang.StringUtils;  
  6. import org.apache.shiro.config.Ini;  
  7. import org.springframework.beans.factory.FactoryBean;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9.   
  10. import java.util.Iterator;  
  11. import java.util.List;  
  12.   
  13. /** 
  14.  * Created by Jeremie on 2014/10/1. 
  15.  */  
  16. public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section> {  
  17.   
  18.     @Autowired  
  19.     private FunctionService functionService;  
  20.   
  21.     //静态资源访问权限  
  22.     private String filterChainDefinitions = "/static/**=anon";  
  23.   
  24.     @Override  
  25.     public Ini.Section getObject() throws Exception {  
  26.         List<Function> list = functionService.findAll();  
  27.         Ini ini = new Ini();  
  28.         //加载默认的url  
  29.         ini.load(filterChainDefinitions);  
  30.         Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);  
  31.         //循环Resource的url,逐个添加到section中。section就是filterChainDefinitionMap,  
  32.         //里面的键就是链接URL,值就是存在什么条件才能访问该链接  
  33.         for (Iterator<Function> it = list.iterator(); it.hasNext(); ) {  
  34.             Function function = it.next();  
  35.             //构成permission字符串  
  36.             if (StringUtils.isNotEmpty(function.getValue()) && StringUtils.isNotEmpty(function.getType())) {  
  37.                 String permission = "";  
  38.                 switch(function.getType()){  
  39.                     case "anon":  
  40.                         permission = "anon";  
  41.                         break;  
  42.                     case "perms":  
  43.                         permission = "perms[" + function.getPermission().getPermissionname() + "]";  
  44.                         break;  
  45.                     case "roles":  
  46.                         permission = "roles[" + function.getRole().getRolename() + "]";  
  47.                         break;  
  48.                     default:  
  49.                         break;  
  50.                 }  
  51.                 section.put(function.getValue(), permission);  
  52.             }  
  53.   
  54.         }  
  55.         //所有资源的访问权限,必须放在最后  
  56.         section.put("/**""authc");  
  57.         return section;  
  58.     }  
  59.   
  60.     @Override  
  61.     public Class<?> getObjectType() {  
  62.         return this.getClass();  
  63.     }  
  64.   
  65.     @Override  
  66.     public boolean isSingleton() {  
  67.         return false;  
  68.     }  
  69. }  
  70. </span>  
四、jsp页面及Controller

登录界面login.jsp

 

[html]   view plain  copy
  1. <%@ page language="java"  pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  4. <html>  
  5. <head>  
  6.     <title>登录页面</title>  
  7.     <script type="text/javascript" src="static/js/md5.js"></script>  
  8. </head>  
  9.   
  10. <body>  
  11. <h1>登录页面----<span style="color: red;">${message }</span></h1>  
  12. <form action="/login.html" name="user" method="post">  
  13.     用户名:<input type="text" name="username"/> <br/>  
  14.     密  码:<input type="password" id="password" name="password"/> <br/>  
  15.     <input type="button" onclick="submitform()" value="登录"/>  
  16.     <input type="reset" value="重置"/>  
  17. </form>  
  18. </body>  
  19. <script type="text/javascript">  
  20.     function submitform(){  
  21.         var password = document.getElementById("password");  
  22.         document.getElementById("password").value = hex_md5(password.value);  
  23.         document.user.submit();  
  24.     }  
  25. </script>  
  26. </html>    
登陆成功后的页面user.jsp

 

[html]   view plain  copy
  1. <%@ page language="java" pageEncoding="UTF-8" %>  
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
  3. <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>  
  4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  5. <html>  
  6. <head>  
  7.     <title>用户列表</title>  
  8.     <script type="text/javascript" src="static/js/jquery-2.0.3.min.js"></script>  
  9. </head>  
  10. <body>  
  11. <h1>${message }</h1>  
  12.   
  13. <h1>用户列表<shiro:hasPermission name="user:add">--<a href="/user/add.html">添加用户</a></shiro:hasPermission>---<a href="/logout.html">退出登录</a></h1>  
  14.   
  15. <h2>权限列表</h2>  
  16. <shiro:authenticated>用户已经登录显示此内容</shiro:authenticated><br/>  
  17. <shiro:hasRole name="manager">manager角色登录显示此内容</shiro:hasRole><br/>  
  18. <shiro:hasRole name="admin">admin角色登录显示此内容</shiro:hasRole><br/>  
  19. <shiro:hasRole name="normal">normal角色登录显示此内容</shiro:hasRole><br/>  
  20. <shiro:hasRole name="user"><p style="color: red;">测试专用!!</p></shiro:hasRole>  
  21. <shiro:hasAnyRoles name="manager,admin">**manager or admin 角色用户登录显示此内容**</shiro:hasAnyRoles><br/>  
  22.   
  23. <p>============================我是邪恶的分割线==========================</p>  
  24.   
  25. <shiro:principal/>-显示当前登录用户名<br/>  
  26. <shiro:hasPermission name="user:add">user:add权限用户显示此内容</shiro:hasPermission><br/>  
  27. <shiro:hasPermission name="user:del">user:del权限用户显示此内容</shiro:hasPermission><br/>  
  28. <shiro:hasPermission name="user:update">user:update权限用户显示此内容</shiro:hasPermission><br/>  
  29. <shiro:hasPermission name="user:query">user:query权限用户显示此内容</shiro:hasPermission><br/>  
  30. <shiro:lacksPermission name="user:add">不具有user:add权限用户显示此内容</shiro:lacksPermission><br/>  
  31. <shiro:lacksPermission name="user:del">不具有user:del权限用户显示此内容</shiro:lacksPermission><br/>  
  32. <shiro:lacksPermission name="user:update">不具有user:update权限用户显示此内容</shiro:lacksPermission><br/>  
  33. <shiro:lacksPermission name="user:query">不具有user:query权限用户显示此内容</shiro:lacksPermission><br/>  
  34.   
  35. <shiro:hasPermission name="user:query">所有用户列表<br/></shiro:hasPermission>  
  36. <ul>  
  37.     <c:forEach items="${userList }" var="user">  
  38.         <li><shiro:hasPermission name="user:query">用户名:${user.username }</shiro:hasPermission>  
  39.             <shiro:hasPermission name="user:query">----密码:${user.password }</shiro:hasPermission>  
  40.             <shiro:hasPermission name="user:update">----<a href="/user/edit.html?id=${user.id}">修改用户</a></shiro:hasPermission>  
  41.             <shiro:hasPermission name="user:del">----<a href="javascript:void(0);" class="del" ref="${user.id }">删除用户</a></shiro:hasPermission>  
  42.         </li>  
  43.     </c:forEach>  
  44. </ul>  
  45. <script type="text/javascript">  
  46.     $(function () {  
  47.         $(".del").click(function () {  
  48.             var id = $(this).attr("ref");  
  49.             $.ajax({  
  50.                 type: "GET",  
  51.                 url: "/user/del.html?id="+id,  
  52.                 success: function (e) {  
  53.                     alert("删除成功(不是真删除,测试而已)");  
  54.                 },  
  55.                 error: function(json){  
  56.                     alert("删除失败");  
  57.                 }  
  58.             });  
  59.         });  
  60.     });  
  61. </script>  
  62. </body>  
  63. </html>  
拥有此权限的页面:success.jsp

 

[html]   view plain  copy
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>  
  2. <html>  
  3. <head>  
  4.     <title></title>  
  5. </head>  
  6. <body>  
  7.     url权限控制:  
  8.     有此权限功能  
  9. </body>  
  10. </html>  

403页面

 

[html]   view plain  copy
  1. <%@ page language="java"  pageEncoding="UTF-8"%>  
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  3. <html>  
  4. <head>  
  5.     <title>权限错误</title>  
  6. </head>  
  7.   
  8. <body>  
  9. <h1>403,You don't have permission to access / on this server</h1>  
  10.   
  11. </body>  
  12. </html>  

静态引用js



UserController.java

如果有对应权限,则会进入此Controller转发到success.jsp,否则会被shiro转发到403.jsp

[java]   view plain  copy
  1. package com.etop.controller;  
  2.   
  3. import com.etop.basic.controller.BaseController;  
  4. import org.springframework.stereotype.Controller;  
  5. import org.springframework.web.bind.annotation.RequestMapping;  
  6. import org.springframework.web.bind.annotation.RequestMethod;  
  7. import org.springframework.web.bind.annotation.ResponseBody;  
  8.   
  9. /** 
  10.  * Created by Jeremie on 2014/10/3. 
  11.  */  
  12. @Controller  
  13. @RequestMapping("/user")  
  14. public class UserController extends BaseController {  
  15.   
  16.     //add,edit,del页面并没有写具体逻辑,要验证是否成功,需要观察控制台输出。  
  17.     @RequestMapping("/add.html")  
  18.     public String addUser(){  
  19.         return "/success.jsp";  
  20.     }  
  21.   
  22.     @RequestMapping("/edit.html")  
  23.     public String updateUser(int id){  
  24.         System.out.println("=========================================>要修改的id为:" + id);  
  25.         return "/success.jsp";  
  26.     }  
  27.   
  28.     @ResponseBody  
  29.     @RequestMapping(value = "/del.html",produces = "text/html; charset=utf-8",method= RequestMethod.GET)  
  30.     public String deleteUser(String id){  
  31.         System.out.println("=========================================>要删除的id为:" + id);  
  32.         return "";  
  33.     }  
  34. }  

HomeController.java
处理用户登录,用户登出

其中SecurityUtils.getSubject().login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));为登录方法

这是shiro的验证的顺序:

 

[java]   view plain  copy
  1. package com.etop.controller;  
  2.   
  3. import javax.validation.Valid;  
  4.   
  5. import com.etop.basic.controller.BaseController;  
  6. import com.etop.service.UserService;  
  7. import org.apache.commons.lang.StringUtils;  
  8. import org.apache.shiro.SecurityUtils;  
  9. import org.apache.shiro.authc.AuthenticationException;  
  10. import org.apache.shiro.authc.UsernamePasswordToken;  
  11. import org.springframework.beans.factory.annotation.Autowired;  
  12. import org.springframework.context.annotation.Bean;  
  13. import org.springframework.stereotype.Controller;  
  14. import org.springframework.ui.Model;  
  15. import org.springframework.validation.BindingResult;  
  16. import org.springframework.web.bind.annotation.ModelAttribute;  
  17. import org.springframework.web.bind.annotation.RequestMapping;  
  18. import org.springframework.web.bind.annotation.RequestMethod;  
  19.   
  20. import com.etop.pojo.User;  
  21. import org.springframework.web.servlet.mvc.support.RedirectAttributes;  
  22.   
  23. import java.util.List;  
  24.   
  25. @Controller  
  26. public class HomeController extends BaseController {  
  27.   
  28.     @Autowired  
  29.     private UserService userService;  
  30.   
  31.     @RequestMapping(value="/login.html",method=RequestMethod.GET,produces = "text/html; charset=utf-8")  
  32.     public String loginForm(Model model,String message){  
  33.         if(!StringUtils.isEmpty(message))  
  34.             model.addAttribute(message);  
  35.         model.addAttribute("user"new User());  
  36.         return "/login.jsp";  
  37.     }  
  38.   
  39.     @RequestMapping(value="/login.html",method=RequestMethod.POST,produces = "text/html; charset=utf-8")  
  40.     public String login(@Valid User user,BindingResult bindingResult,Model model,RedirectAttributes attr){  
  41.         try {  
  42.             if(bindingResult.hasErrors()){  
  43.                 addMessage(attr, "用户名或密码错误");  
  44.                 return "redirect:/login.html";  
  45.             }  
  46.             //使用shiro管理登录  
  47.             SecurityUtils.getSubject().login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));  
  48.             //获取所有用户信息,权限由前端shiro标签控制  
  49.             List<User> userList = userService.getAllUser();  
  50.             model.addAttribute("userList", userList);  
  51.             return "/user.jsp";  
  52.         } catch (AuthenticationException e) {  
  53.             addMessage(attr, "用户名或密码错误");  
  54.             return "redirect:/login.html";  
  55.         }  
  56.     }  
  57.   
  58.     @RequestMapping(value="/logout.html",method=RequestMethod.GET)  
  59.     public String logout(RedirectAttributes attr){  
  60.         //使用权限管理工具进行用户的退出,注销登录  
  61.         SecurityUtils.getSubject().logout();  
  62.         addMessage(attr, "您已安全退出");  
  63.         return "redirect:/login.html";  
  64.     }  
  65.   
  66.     @RequestMapping("/403.html")  
  67.     public String unauthorizedRole(){  
  68.         return "/403.jsp";  
  69.     }  
  70. }   


五、补充内容,有关网页权限的注解配置,详见项目第二个分支

po主几经波折,终于把使用注解的方式来通过权限来控制url的访问给弄好了。

首先附上经过修改后的userController注解版(具体用法)

 

[java]   view plain  copy
  1. package com.etop.controller;  
  2.   
  3. import com.etop.basic.controller.BaseController;  
  4. import org.apache.shiro.authz.UnauthorizedException;  
  5. import org.apache.shiro.authz.annotation.RequiresPermissions;  
  6. import org.springframework.stereotype.Controller;  
  7. import org.springframework.web.bind.annotation.RequestMapping;  
  8. import org.springframework.web.bind.annotation.RequestMethod;  
  9. import org.springframework.web.bind.annotation.ResponseBody;  
  10.   
  11. /** 
  12.  * 处理用户操作的控制器 
  13.  * 
  14.  * Created by Jeremie on 2014/10/3. 
  15.  */  
  16. @Controller  
  17. @RequestMapping("/user")  
  18. public class UserController extends BaseController {  
  19.   
  20.     @RequiresPermissions(value = "user:add")  
  21.     @RequestMapping("/add.html")  
  22.     public String addUser() throws UnauthorizedException {  
  23.         return "/success.jsp";  
  24.     }  
  25.   
  26.     @RequiresPermissions(value = "user:edit")  
  27.     @RequestMapping("/edit.html")  
  28.     public String updateUser(int id){  
  29.         System.out.println("=========================================>要修改的id为:" + id);  
  30.         return "/success.jsp";  
  31.     }  
  32.   
  33.     @RequiresPermissions(value = "user:del")  
  34.     @ResponseBody  
  35.     @RequestMapping(value = "/del.html",produces = "text/html; charset=utf-8",method= RequestMethod.GET)  
  36.     public String deleteUser(String id){  
  37.         System.out.println("=========================================>要删除的id为:" + id);  
  38.         return "";  
  39.     }  
  40.   
  41.   
  42. }  

备注:(附各种权限的注解)

1)@RequiresAuthentication 需要通过验证后的权限

2)@RequiresGuest 游客权限可以通过

3)@RequiresPermissions("user:add") 需要当前角色拥有user:add权限才能通过

4)@RequiresRoles("admin") 需要admin角色才能通过

5)@RequiresUser 需要有已知身份的角色才能通过

6)若不具备权限,程序会抛出UnauthorizedException,可以对其进行捕获处理(这里的处理是跳到403页面)

 

[java]   view plain  copy
  1. @ExceptionHandler(Exception.class)  
  2.     public String handleException(Exception ex, HttpServletRequest request){  
  3.         if(ex instanceof UnauthorizedException){  
  4.             log.error("当前用户没有此权限");  
  5.             return "/403.jsp";  
  6.         }else {  
  7.             log.error("系统发生异常", ex);  
  8.             ex.printStackTrace();  
  9.             request.setAttribute("exMsg", ex.getMessage());  
  10.             return "errors/exception";  
  11.         }  
  12.     }  

相关配置(重要,po主就是因为漏了这段配置,一直没能成功截获):

springmvc_servlet.xml:

 

[html]   view plain  copy
  1.     <context:component-scan base-package="com.etop" use-default-filters="false">  
  2.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
  3.         <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>  
  4.     </context:component-scan>  
  5.     <aop:config proxy-target-class="true"></aop:config>  
  6.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  7.         <property name="securityManager" ref="securityManager"/>  
  8.     </bean>  
  9.     <context:component-scan base-package="com.etop.controller"/>  

<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>

<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>

扫描Controller的时候,必须把shiro的注解部分进行扫描

另外,分支二加入了缓存的配置方式,具体在项目中体现。

最后,为方便大家,再次附上项目链接:

 

项目:https://git.oschina.net/jeremie_astray/SpringMVC_Shiro/tree/master/

Annotion版本:https://git.oschina.net/jeremie_astray/SpringMVC_Shiro/tree/shiro_annotation

 
 

猜你喜欢

转载自xiaoqiufeng.iteye.com/blog/2279014