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配置如下:

  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的配置
  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的配置

  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的配置
  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:

  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

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

  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

  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

  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頁面

  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

  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的驗證的順序:


  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註解版(具體用法)

  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頁面)

  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:

  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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章