Shiro的使用与配置实战

20 篇文章 0 订阅
7 篇文章 0 订阅

1.关于Shiro在Spring中的配置

1.直接在HIbernate中使用Ehcache的配置


[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"    
  4.  xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"    
  5.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  6.  xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"   
  7.  xmlns:task="http://www.springframework.org/schema/task"  
  8.  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     
  9.    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd     
  10.    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd     
  11.    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd   
  12.     http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring   
  13.     http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd   
  14.     http://www.springframework.org/schema/task    
  15. http://www.springframework.org/schema/task/spring-task-4.1.xsd">    
  16.   
  17.     <context:annotation-config/>  
  18.     <!-- 启动对@AspectJ注解的支持,为了事务处理和Aop处理日志 -->    
  19.     <aop:aspectj-autoproxy />  
  20.   
  21.     <context:component-scan base-package="com.jay.platform" />  
  22.     <!-- 读取Properties文件配置信息 -->  
  23.     <context:property-placeholder location="classpath:jdbc.properties"  
  24.         ignore-unresolvable="true" />  
  25.           
  26.     <!-- 数据库连接池,DBCP -->  
  27.     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
  28.         destroy-method="close">  
  29.         <property name="driverClassName" value="${jdbc.driverClassName}" />  
  30.         <property name="url" value="${jdbc.url}" />  
  31.         <property name="username" value="${jdbc.username}" />  
  32.         <property name="password" value="${jdbc.password}" />  
  33.         <property name="timeBetweenEvictionRunsMillis">  
  34.             <value>3600000</value><!--1 hours -->  
  35.         </property>  
  36.         <property name="minEvictableIdleTimeMillis">  
  37.             <value>28800000</value><!--8 hours -->  
  38.         </property>  
  39.     </bean>  
  40.       
  41.       
  42.    <!-- Hibernate4中使用以下配置方式 -->  
  43.    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">   
  44.         <property name="dataSource" ref="dataSource" />  
  45.        <!--  采用注解形式配置对象关系映射信息 -->    
  46.         <property name="packagesToScan">   
  47.               <list>   
  48.                    <value>com.jay.platform.*</value>   
  49.               </list>   
  50.         </property>  
  51.         <property name="hibernateProperties">    
  52.             <props>    
  53.                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>    
  54.                 <prop key="hibernate.show_sql">true</prop>    
  55.                 <prop key="hibernate.format_sql">true</prop>    
  56.                 <prop key="hibernate.hbm2ddl.auto">update</prop>    
  57.                 <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>     
  58.                <!--  最大抓取深度,如果为0,则关闭默认的外连接抓取。建议值为0-3   -->  
  59.                 <prop key="hibernate.max_fetch_depth">3</prop>    
  60.                <!--  用于生成有助于调试的注释信息,默认为关闭   -->  
  61.                 <prop key="hibernate.use_sql_comments">true</prop>  
  62.                 <prop key="connection.autocommit">true</prop>    
  63.                   
  64.                 <!-- Hibernate配置EhCache 用作二级缓存 -->  
  65.                 <prop key="hibernate.cache.use_second_level_cache">true</prop>  
  66.                 <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>   
  67.                 <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>  
  68.                 <prop key="hibernate.cache.use_query_cache">true</prop>  
  69.                 <prop key="cache.provider_configuration_file_resource_path">ehcache.xml</prop>  
  70.             </props>    
  71.         </property>    
  72.               
  73.     </bean>    
  74.       
  75.    <!-- 配置事务管理器 -->  
  76.     <bean id="txManager"  
  77.           class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
  78.         <property name="sessionFactory" ref="sessionFactory" />  
  79.     </bean>  
  80.    
  81.     <!-- 配置事务异常封装-->  
  82.     <bean id="persistenceExceptionTranslationPostProcessor"  
  83.           class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>  
  84.    
  85.     <!-- 声明式容器事务管理-->  
  86.     <tx:advice id="txAdvice" transaction-manager="txManager">  
  87.         <tx:attributes>  
  88.             <tx:method name="save*" propagation="REQUIRED" />  
  89.             <tx:method name="add*" propagation="REQUIRED" />  
  90.             <tx:method name="create*" propagation="REQUIRED" />  
  91.             <tx:method name="insert*" propagation="REQUIRED" />  
  92.             <tx:method name="update*" propagation="REQUIRED" />  
  93.             <tx:method name="merge*" propagation="REQUIRED" />  
  94.             <tx:method name="del*" propagation="REQUIRED" />  
  95.             <tx:method name="remove*" propagation="REQUIRED" />  
  96.             <tx:method name="put*" propagation="REQUIRED" />  
  97.             <tx:method name="use*" propagation="REQUIRED"/>  
  98.             <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->  
  99.             <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
  100.             <tx:method name="count*" propagation="REQUIRED" read-only="true" />  
  101.             <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
  102.             <tx:method name="list*" propagation="REQUIRED" read-only="true" />  
  103.             <tx:method name="*" read-only="true" />  
  104.         </tx:attributes>  
  105.     </tx:advice>  
  106.     <aop:config expose-proxy="true">  
  107.         <!-- 只对业务逻辑层实施事务 -->  
  108.         <aop:pointcut id="txPointcut" expression="execution(* com.jay.platform.service..*.*(..))" />  
  109.         <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>  
  110.     </aop:config>  
  111.       
  112.       
  113.     <!-- Shiro相关配置 -->  
  114.     <bean id="authorityFilter" class="com.jay.platform.filter.AuthorityFilter" />  
  115.     <bean id="userRealm" class="com.jay.platform.shiro.UserRealm" />  
  116.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  117.         <property name="realm" ref="userRealm"></property>  
  118.     </bean>  
  119.   
  120.     <!-- logout后返回的页面 -->  
  121.     <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">  
  122.      <property name="redirectUrl" value="/index.htm" />  
  123.      </bean>  
  124.       
  125.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  126.         <property name="securityManager" ref="securityManager"></property>  
  127.         <!-- 登录Url -->  
  128.         <property name="loginUrl" value="/index.htm"></property>  
  129.         <!-- 未授权要跳转到的url -->  
  130.         <property name="unauthorizedUrl" value="/index.htm"></property>   
  131.         <!-- 配置的过滤器 -->  
  132.         <property name="filters">  
  133.             <map>  
  134.                 <entry key="authc" value-ref="authorityFilter" />   
  135.                 <entry key="logout" value-ref="logoutFilter" />  
  136.             </map>  
  137.         </property>  
  138.         <property name="filterChainDefinitions">  
  139.             <value>  
  140.                 /resources/*/**=anon  
  141.                 /index.htm=anon  
  142.                 /getCode.htm=anon  
  143.                   
  144.                 /**=authc  
  145.                /home.htm=authc  
  146.              <!--   /system/user/**= perms["sys:user:add,sys:user:update"] -->  
  147.             </value>  
  148.         </property>  
  149.     </bean>  
  150.       
  151.     <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  
  152.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  153.       
  154.     <!-- AOP式方法级权限检查  -->  
  155.     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">  
  156.     </bean>  
  157.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  158.         <property name="securityManager" ref="securityManager"/>  
  159.     </bean>  
  160.       
  161.     <!-- Spring MVC的统一异常处理 -->  
  162.     <bean id="exceptionResolver" class="com.jay.platform.exception.handler.ExceptionHandler"/>    
  163.       
  164.        
  165.      <!-- 引入定时器框架Quartz的配置 -->  
  166.     <!-- <import resource="quartz-config.xml"/> -->  
  167.   
  168.     <!-- 通过注解的形式,执行定时器 -->  
  169.  <!-- 配置Spring定时器,扫描注解 -->  
  170.     <!-- <task:annotation-driven/>  -->  
  171.       
  172.       
  173. </beans>  


2.在Shiro中使用了Ehcache的配置

[html]  view plain  copy
  1. <!-- shiro start -->  
  2.  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  3.  <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
  4.      <property name="cacheManagerConfigFile"  
  5.          value="classpath:ehcache.xml" />  
  6.  </bean>  
  7.  <bean id="credentialsMatcher"  
  8.      class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">  
  9.      <property name="hashAlgorithmName" value="SHA-256" />  
  10.  </bean>  
  11.  <bean id="iniRealm" class="com.boonya.shiro.security.CurrentIniRealm">  
  12.      <constructor-arg type="java.lang.String" value="classpath:shiro.ini" />  
  13.      <property name="credentialsMatcher" ref="credentialsMatcher" />  
  14.  </bean>  
  15.  <bean id="userRealm" class="com.boonya.shiro.security.UserRealm" />  
  16.  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  17.      <property name="realms">  
  18.          <list>  
  19.              <ref bean="iniRealm" />  
  20.              <ref bean="userRealm" />  
  21.          </list>  
  22.      </property>  
  23.      <property name="cacheManager" ref="cacheManager" />  
  24.  </bean>  
  25.  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  26.      <property name="securityManager" ref="securityManager" />  
  27.      <property name="loginUrl" value="/login" />  
  28.      <property name="successUrl" value="/maps/main.html"></property>  
  29.      <property name="unauthorizedUrl" value="/unauthorized"></property>  
  30.      <property name="filters">  
  31.          <util:map>  
  32.              <entry key="anAlias">  
  33.                  <bean  
  34.                      class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter" />  
  35.              </entry>  
  36.          </util:map>  
  37.      </property>  
  38.      <property name="filterChainDefinitions">  
  39.          <value>  
  40.              /unauthorized=anon  
  41.              /validate/code*=anon  
  42.              /login/**=anon  
  43.              /image/**=anon  
  44.              /js/**=anon  
  45.              /css/**=anon  
  46.              /common/**=anon  
  47.              /index.htm* = anon  
  48.              /maps/**=authc              
  49.         </value>  
  50.      </property>  
  51.  </bean>  


3.web.xml中shiroFilter配置

[html]  view plain  copy
  1. <filter>  
  2.     <filter-name>shiroFilter</filter-name>  
  3.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  4.   </filter>  
  5.   <filter-mapping>  
  6.     <filter-name>shiroFilter</filter-name>  
  7.     <url-pattern>/*</url-pattern>  
  8.   </filter-mapping>  


4.关于Shiro配置的过滤属性的说明:

securityManager:这个属性是必须的

loginUrl :没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。

successUrl :登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。

unauthorizedUrl :没有权限默认跳转的页面。

===============其权限过滤器及配置释义=======================

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
anon   org.apache.shiro.web.filter.authc.AnonymousFilter
 
authc  org.apache.shiro.web.filter.authc.FormAuthenticationFilter
 
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
 
perms  org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
 
port   org.apache.shiro.web.filter.authz.PortFilter
 
rest   org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
 
roles  org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
 
ssl    org.apache.shiro.web.filter.authz.SslFilter
 
user   org.apache.shiro.web.filter.authc.UserFilter
 
logout org.apache.shiro.web.filter.authc.LogoutFilter

anon:例子/admins/**=anon 没有参数,表示可以匿名使用。

authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数

roles例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。

perms例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"]当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。

rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中methodpostgetdelete等。

port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议httphttps等,serverName是你访问的host,8081url配置里port的端口,queryString

是你访问的url里的?后面的参数。

authcBasic例如/admins/user/**=authcBasic没有参数表示httpBasic认证

ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https

user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查

注:anonauthcBasicauchcuser是认证过滤器,

permsrolessslrestport是授权过滤器



2.参考Shiro框架权限实践


.spring集成shiro

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3.   
  4. <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
  6.          version="2.5">  
  7.     <welcome-file-list>  
  8.         <welcome-file>login.jsp</welcome-file>  
  9.     </welcome-file-list>  
  10.       
  11. <!-- 加载spring的配置****begin -->  
  12.     <listener>  
  13.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  14.     </listener>  
  15.     <context-param>  
  16.         <param-name>contextConfigLocation</param-name>  
  17.         <param-value>classpath*:config/spring/appCtx-*.xml</param-value>  
  18.     </context-param>  
  19. <!-- 加载spring的配置****end -->  
  20.   
  21. <!-- 加载Log4j的配置****begin -->  
  22.     <context-param>    
  23.         <param-name>log4jConfigLocation</param-name>    
  24.         <param-value>/WEB-INF/classes/log4j.properties</param-value>    
  25.     </context-param>   
  26.     <listener>  
  27.         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
  28.     </listener>  
  29. <!-- 加载Log4j的配置****end -->      
  30.      
  31. <!--   
  32.   解决Hibernate的Session的关闭与开启问题  
  33.   功能是用来把一个Hibernate Session和一次完整的请求过程对应的线程相绑定。目的是为了实现"Open Session in View"的模式。例如: 它允许在事务提交之后延迟加载显示所需要的对象  
  34.  -->      
  35.     <filter>  
  36.         <filter-name>openSessionInViewFilter</filter-name>  
  37.          <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>  
  38.     </filter>  
  39.     <filter-mapping>  
  40.         <filter-name>openSessionInViewFilter</filter-name>  
  41.         <url-pattern>/*</url-pattern>  
  42.     </filter-mapping>  
  43.      
  44. <!-- 加载shiro的配置*********begin***** -->     
  45.     <filter>  
  46.         <filter-name>shiroFilter</filter-name>  
  47.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  48.         <init-param>    
  49.             <param-name>targetFilterLifecycle</param-name>    
  50.             <param-value>true</param-value>    
  51.         </init-param>   
  52.     </filter>  
  53.     <filter-mapping>  
  54.         <filter-name>shiroFilter</filter-name>  
  55.         <url-pattern>/*</url-pattern>  
  56.     </filter-mapping>  
  57. <!-- 加载shiro的配置*********end***** -->         
  58.       
  59. <!-- 加载struts2的配置******begin****** -->      
  60.      <filter>  
  61.         <filter-name>struts2</filter-name>  
  62.         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  63.     </filter>  
  64.     <filter-mapping>  
  65.         <filter-name>struts2</filter-name>  
  66.         <url-pattern>/*</url-pattern>  
  67.     </filter-mapping>  
  68. <!-- 加载struts2的配置*******end********* -->   
  69. </web-app>  

2.shiro的主要配置文件shiro.xml文件:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?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:tx="http://www.springframework.org/schema/tx"  
  6.        xmlns:util="http://www.springframework.org/schema/util"  
  7.        xmlns:context="http://www.springframework.org/schema/context"  
  8.        xsi:schemaLocation="  
  9.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
  10.        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
  11.        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
  12.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd  
  13.        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
  14.        ">  
  15. <!-- 自动扫描加载spring的bean*****begin********* -->         
  16.    <context:annotation-config />  
  17.    <context:component-scan base-package="com" />  
  18. <!-- 自动扫描加载spring的bean*****end********* -->  
  19.   
  20. <!-- 加载spring的properties文件*****begin********* -->             
  21.    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  22.         <property name="fileEncoding" value="utf-8" />  
  23.         <property name="locations">  
  24.             <list>  
  25.                <value>classpath*:/config/properties/deploy.properties</value>  
  26.             </list>  
  27.         </property>  
  28.     </bean>  
  29. <!-- 加载spring的properties文件*****end******** -->          
  30.       
  31.       
  32. <!-- 加载数据库的相关连接****************begin********** -->  
  33.     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">   
  34.         <!-- 基本属性 url、user、password -->  
  35.         <property name="url" value="${datasource.url}" />  
  36.         <property name="username" value="${datasource.username}" />  
  37.         <property name="password" value="${datasource.password}" />  
  38.         <property name="driverClassName" value="${datasource.driverClassName}"></property>  
  39.   
  40.         <!-- 配置初始化大小、最小、最大 -->  
  41.         <property name="initialSize" value="${druid.initialPoolSize}" />  
  42.         <property name="minIdle" value="${druid.minPoolSize}" />   
  43.         <property name="maxActive" value="${druid.maxPoolSize}" />  
  44.   
  45.         <!-- 配置获取连接等待超时的时间 -->  
  46.         <property name="maxWait" value="${druid.maxWait}" />  
  47.   
  48.         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->  
  49.         <property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}" />  
  50.   
  51.         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->  
  52.         <property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" />  
  53.   
  54.         <property name="validationQuery" value="${druid.validationQuery}" />  
  55.         <property name="testWhileIdle" value="${druid.testWhileIdle}" />  
  56.         <property name="testOnBorrow" value="${druid.testOnBorrow}" />  
  57.         <property name="testOnReturn" value="${druid.testOnReturn}" />  
  58.   
  59.         <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->  
  60.         <property name="poolPreparedStatements" value="${druid.poolPreparedStatements}" />  
  61.         <property name="maxPoolPreparedStatementPerConnectionSize" value="${druid.maxPoolPreparedStatementPerConnectionSize}" />  
  62.   
  63.         <!-- 配置监控统计拦截的filters,如需防御SQL注入则加入wall -->  
  64.         <property name="filters" value="${druid.filters}" />  
  65.         <property name="connectionProperties" value="${druid.connectionProperties}" />  
  66.     </bean>  
  67.       
  68.     <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
  69.         <property name="dataSource" ref="dataSource"/>  
  70. <!--     <property name="packagesToScan">-->  
  71. <!--         <list>-->  
  72. <!--             <value>com.wenc.*.po</value>-->  
  73. <!--         </list>-->  
  74. <!--     </property>-->  
  75.         <property name="packagesToScan"  
  76.             value="com.wenc.core.po" />  
  77. <!--     <property name="mappingLocations"> 此处添加Java类和数据库表的映射关系|mappingLocations代替mappingResources  -->  
  78. <!--         <list>-->  
  79. <!--             <value>classpath:/com/wec/po/**/*.hbm.xml</value>   -->  
  80. <!--         </list>-->  
  81. <!--     </property>-->  
  82.         <property name="hibernateProperties">  
  83.             <props>  
  84.                <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>  
  85.                 <prop key="hibernate.dialect">${hibernate.dialect}</prop>  
  86.                 <prop key="hibernate.hbm2ddl.auto">update</prop>  
  87.                 <prop key="hibernate.show_sql">true</prop>  
  88.                 <prop key="hibernate.format_sql">true</prop>  
  89.                 <prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>  
  90.                 <prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size}</prop>  
  91.                 <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>  
  92.                 <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>  
  93.                 <prop key="hibernate.bytecode.use_reflection_optimizer">${hibernate.bytecode.use_reflection_optimizer}</prop>  
  94.                 <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>  
  95.                 <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>  
  96.                 <prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>  
  97.                 <prop key="net.sf.ehcache.configurationResourceName">${net.sf.ehcache.configurationResourceName}</prop>  
  98.                 <prop key="hibernate.cache.use_structured_entries">${hibernate.cache.use_structured_entries}</prop>  
  99.             </props>  
  100.         </property>  
  101.     </bean>  
  102. <!-- 加载数据库的相关连接****************end********** -->  
  103.   
  104. <!-- spring的事务控制****************begin********** -->  
  105.     <!-- 开启AOP监听 只对当前配置文件有效 -->  
  106.     <aop:aspectj-autoproxy expose-proxy="true"/>  
  107.   
  108.     <!-- 开启注解事务 只对当前配置文件有效 -->  
  109.     <tx:annotation-driven transaction-manager="transactionManager"/>  
  110.           
  111.     <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
  112.         <property name="sessionFactory">  
  113.             <ref bean="sessionFactory" />  
  114.         </property>  
  115.         <property name="globalRollbackOnParticipationFailure" value="true" />  
  116.     </bean>  
  117.   
  118.     <tx:advice id="transactionAdvice" transaction-manager="transactionManager">  
  119.         <tx:attributes>  
  120.             <tx:method name="do*" propagation="REQUIRED" />  
  121.             <tx:method name="save*" propagation="REQUIRED" />  
  122.             <tx:method name="up*" propagation="REQUIRED" />  
  123.             <tx:method name="del*" propagation="REQUIRED" />  
  124.             <tx:method name="sear*"  propagation="REQUIRED" read-only="true" />  
  125.             <tx:method name="search*"  propagation="REQUIRED" read-only="true" />  
  126.             <tx:method name="find*"  propagation="REQUIRED" read-only="true" />  
  127.             <tx:method name="get*"  propagation="REQUIRED" read-only="true" />  
  128.         </tx:attributes>  
  129.     </tx:advice>  
  130.     <aop:config expose-proxy="true" proxy-target-class="true">  
  131.         <aop:pointcut id="txPointcut" expression="execution(* com.wenc.*.service.*.*(..))" />          
  132.         <aop:advisor advice-ref="transactionAdvice" pointcut-ref="txPointcut" order="1"/>  
  133.     </aop:config>  
  134. <!-- spring的事务控制****************end********** -->  
  135.    
  136. <!-- shiro的配置*************************begin********** -->  
  137.    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  138.         <!-- 自定义的realm -->  
  139.         <property name="realm" ref="sampleRealmService"/>  
  140.     </bean>  
  141.       
  142.      <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->  
  143.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  144.     
  145.    
  146.    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  147.         <property name="securityManager" ref="securityManager"/>  
  148.         <!-- 登陆页面的连接 -->  
  149.         <property name="loginUrl" value="/login.jsp"/>  
  150.         <!-- 身份验证后跳转的连接 -->  
  151.         <property name="successUrl" value="/loginAction.action"/>  
  152.         <property name="unauthorizedUrl" value="/unauthorized.jsp"/>  
  153.         <property name="filters">  
  154.             <util:map>  
  155.                 <entry key="authc">  
  156.                     <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>  
  157.                 </entry>  
  158.             </util:map>  
  159.         </property>  
  160.         <!-- 指定过滤器  
  161.             Anon:不指定过滤器,不错是这个过滤器是空的,什么都没做,跟没有一样。   
  162.             Authc:验证,这些页面必须验证后才能访问,也就是我们说的登录后才能访问。   
  163.             这里还有其他的过滤器,我没用,比如说授权  
  164.          -->  
  165.         <property name="filterChainDefinitions">  
  166.             <value>  
  167.                 /loginAction.action=anon  
  168.                 /** = authc  
  169.             </value>  
  170.         </property>  
  171.     </bean>  
  172. <!-- shiro的配置*************************end********** -->       
  173. </beans>  

3.主要的实现类有三个分别是PersonAction,UserPermissionInterceptor,SampleRealmService,这三个之间的相互协作完成了shiro的整个认证和授权过程,下面我们来看各个类的作用:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.wenc.test.service.web;  
  2.   
  3. @Controller  
  4. public class PersonAction extends BaseAction implements ModelDriven<User> {  
  5.   
  6.     private static Logger logger =Logger.getLogger(SampleRealmService.class);  
  7.       
  8.     @Autowired  
  9.     private PersonService personService;  
  10.       
  11.       
  12.     public String login()throws Exception{  
  13.         //对用户输入的密码进行MD5加密  
  14.         String newPassword = CipherUtil.MD5Encode(info.getPassword());  
  15.         logger.info(info.getUsername()+"="+info.getPassword());  
  16.         Subject currentUser = SecurityUtils.getSubject();    
  17.           
  18.         UsernamePasswordToken token = new UsernamePasswordToken(  info.getUsername(), newPassword);  
  19.                 //token.setRememberMe(true); //是否记住我   
  20.                 try {    
  21.                 /**currentUser.login(token) 提交申请,验证能不能通过,也就是交给shiro。这里会回调reaml(或自定义的realm)里的一个方法  
  22.                                 protected AuthenticationInfo doGetAuthenticationInfo() */  
  23.                      currentUser.login(token);    
  24.                 } catch (AuthenticationException e) { //验证身份失败   
  25.                      logger.info("验证登陆客户身份失败!");    
  26.                      this.addActionError("用户名或密码错误,请重新输入!");  
  27.                      return "fail";  
  28.                 }    
  29.           
  30.                 /**Shiro验证后,跳转到此处,这里判断验证是否通过 */  
  31.                 if(currentUser.isAuthenticated()){  //验证身份通过  
  32.                  return SUCCESS;  
  33.                 }else{    
  34.                  this.addActionError("用户名或密码错误,请重新输入!");  
  35.                      return "fail";  
  36.                  }    
  37.   
  38.     }  
  39.       
  40. }  

这个类的login方法是当我们输入用户名和密码之后,点击登录按钮所执行的方法,由于在数据库中用户的密码是密文形式,所以在进行用户身份验证,我们必须以同样的加密方式来加密用户在页面上输入的密码,然后将用户名和加密后的密码放入令牌(也就是token中),之后shiro会通过比对token中的用户名和密码是否与数据库中存放的真正的用户名和密码来确定用户是否为合法用户,而这个验证过程是shiro为我们完成的,当执行currentUser.login(token)方法的时候会触发验证过程,但是通常情况下这个验证过程是通过我们来自定义完成的,为此我们必须自己写一个realm类来继承shiro的AuthorizingRealm类并覆盖其AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)方法,来看SampleRealmService类,这个就是继承AuthorizingRealm并覆盖其方法后的类:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.wenc.core.service;  
  2.   
  3. @Component  
  4. public class SampleRealmService extends AuthorizingRealm {  
  5.   
  6.     private static Logger logger =Logger.getLogger(SampleRealmService.class);  
  7.     @Autowired  
  8.     private PersonDAO personDAO;  
  9.   
  10.   
  11.     public SampleRealmService() {  
  12.         logger.info("-------AAA1------------------");  
  13.         setName("sampleRealmService");  
  14.        // setCredentialsMatcher(new Sha256CredentialsMatcher());  
  15.     }  
  16.   
  17.       
  18.     /** 
  19.      * 身份验证 
  20.      * @param authcToken 登陆Action封装的令牌 
  21.      */  
  22.     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {  
  23.         UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
  24.         /**查询对应的用户是否存在*/  
  25.         User user =personDAO.getUser(token.getUsername(), token.getPassword().toString());  
  26.         logger.info(user);  
  27.         if( user != null ) {  
  28.             return new SimpleAuthenticationInfo(user.getId(), user.getPassword(), getName());  
  29.         } else {  
  30.             return null;  
  31.         }  
  32.     }  
  33.     /** 
  34.      * 授权 
  35.      * 注意:统一在struts的拦截器中处理,见UserPermissionInterceptor.java 
  36.      */  
  37.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
  38.         Integer userId = (Integer) principals.fromRealm(getName()).iterator().next();  
  39.         logger.info("用户ID:"+userId);  
  40.         User user = personDAO.getUser(userId);  
  41.         if( user != null ) {  
  42.             SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  43.             for( Role role : user.getRoles() ) {  
  44.                 info.addRole(role.getName());  
  45.                 Set<Perms> set= role.getPermissions();  
  46.                 logger.info(set);  
  47.                 for(Perms perm:set){  
  48.                     info.addStringPermission(perm.getActionName());  
  49.                 }  
  50.             }  
  51.             return info;  
  52.         } else {  
  53.             return null;  
  54.         }  
  55.     }  
  56.   
  57. }  


如同上面介绍的那样执行验证的过程就进入了身份认证方法体中,也就是在这里讲数据库中查询出来的真实的用户信息和token中的用户信息进行比对,当验证成功后跳转至strut.xml中配置的index.jsp页面,截图如下:

至此我们完成了用户身份验证过程,接下来我们介绍授权过程和通过shiro标签来介绍细粒度的权限控制。当我们点击“主页2”这个超链接的时候会被struts.xml文件中定义的拦截器拦截,拦截器UserPermissionInterceptor代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.wenc.core.web.interceptor;  
  2.   
  3. public class UserPermissionInterceptor extends AbstractInterceptor {  
  4.   
  5.     private static final long serialVersionUID = -2185920708747626659L;  
  6.     private static final Log logger = LogFactory.getLog(UserPermissionInterceptor.class);  
  7.       
  8.      @Override  
  9.     public String intercept(ActionInvocation invocation) throws Exception {  
  10.         ActionContext ac = invocation.getInvocationContext();  
  11.         Map map = ac.getParameters();  
  12.   
  13.         String actionName = ac.getName();  
  14.         String methodName = "";  
  15.                 String[] _methodName = (String[]) map.get("method");  
  16.             if (_methodName != null) {  
  17.             methodName = _methodName[0];  
  18.         }  
  19.         logger.info("actionName:"+actionName+",方法名:"+methodName);  
  20.   
  21.         Subject currentUser = SecurityUtils.getSubject();   
  22.         /**判断是否已经授权*/  
  23.         if(!currentUser.isPermitted(actionName)){   
  24.              logger.info("没有有权限");  
  25.          }  
  26.         return invocation.invoke();  
  27.      }  
  28. }  
当点击“主页2”之后会首先被该拦截器拦截,拦截的过程中会将当前请求(即点击“主页2”对应的action)的action名称取出,我们要验证的就是该用户是否享有对该action的权限,执行到currentUser.isPermitted(actionName)方法的时候就触发了shiro的授权认证功能,同样我们也对这个方法进行了重写,进入的是SampleRealmService类中的授权方法AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals),在这个函数中我们取出了数据库中配置的该用户的权限,并将用户的所有权限加入到info中,然后返回请求页面,当加载请求页面的时候执行到shiro标签的时候会再次触发授权(注意这次将不被拦截),相当于再次从数据库中将该用户的权限加载了一遍,并且放入到info中,然后shiro标签会根据shiro:hasPermission或者是shiro:hasRole进行比对,如果存在则显示,否则不显示,当然shiro标签除了这两种方式外还有很多种其他的方式,大家可以自行探索
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值