zoukankan      html  css  js  c++  java
  • shiro与spring集成

    简介

    Apache Shiro 是 Java 的一个安全(权限)框架。主要提供了认证、授权、加密和会话管理等功能。

    Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
    Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用
    户是否能进行什么操作,如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户
    对某个资源是否具有某个权限;
    Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有
    信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
    Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
    Web Support:Web 支持,可以非常容易的集成到Web 环境;
    Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可
    以提高效率;
    Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能
    把权限自动传播过去;
    Testing:提供测试支持;
    Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
    Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登
    录了。

    集成Spring

    工程目录

    1、引入依赖

    <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.0</version>
                <scope>provided</scope>
            </dependency>
    
            <!-- spring webmvc相关jar -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
    
            <!-- spring相关jar -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>4.0.0.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
    
            <!-- log -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.21</version>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.21</version>
            </dependency>
    
            <!-- mysql  -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.28</version>
            </dependency>
    
            <!-- json -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.3.0</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.3.0</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.3.0</version>
                <exclusions>
                    <exclusion>
                        <artifactId>jackson-annotations</artifactId>
                        <groupId>com.fasterxml.jackson.core</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <!-- web jstl的jar -->
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
    
            <!-- ehcache的jar -->
            <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
                <version>2.8.0</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-ehcache</artifactId>
                <version>1.0.0</version>
            </dependency>
    
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.3</version>
            </dependency>
    
            <!--shiro -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-aspectj</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.3.2</version>
            </dependency>
    
        </dependencies>

    2、Spring配置文件

    applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
            
            
        <context:component-scan base-package="org.tarena">
            <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Controller" />
        </context:component-scan>    
    
        <aop:aspectj-autoproxy proxy-target-class="true"/>     
        
        <import resource="classpath*:/spring-*.xml" />
            
    </beans>

    spring-mvc.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
        
        <!-- 开启controller注解支持 -->
        <context:component-scan base-package="org.tarena.shiro"
            use-default-filters="false">
            <context:include-filter type="annotation"
                expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
        
        <mvc:annotation-driven></mvc:annotation-driven>
        <mvc:default-servlet-handler/>
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    </beans>

    spring-shiro.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!-- =========================================================
             Shiro Core Components - Not Spring Specific
             ========================================================= -->
        <!-- Shiro's main business-tier object for web-enabled applications
             (use DefaultSecurityManager instead when there is no web environment)-->
        <!--  
        1. 配置 SecurityManager!
        -->     
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="cacheManager" ref="cacheManager"/>
            <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
            <property name="sessionMode" value="native"/>
            <property name="realms">
                <list>
                    <ref bean="myRealm"/>
                    <ref bean="secondRealm"/>
                </list>
            </property>
            
        </bean>
        
        <bean id="myRealm" class="org.tarena.shiro.realm.MyRealm">
            <property name="credentialsMatcher" >
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <property name="hashAlgorithmName" value="MD5"></property>
                    <property name="hashIterations" value="1024"></property>
                </bean>
            </property>
        </bean>
        
        
        <bean id="secondRealm" class="org.tarena.shiro.realm.SecondRealm">
            <property name="credentialsMatcher" >
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <property name="hashAlgorithmName" value="SHA1"></property>
                    <property name="hashIterations" value="1024"></property>
                </bean>
            </property>
        </bean>
        
    
        <!-- Let's use some enterprise caching support for better performance.  You can replace this with any enterprise
             caching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc -->
        <!--  
        2. 配置 CacheManager. 
        2.1 需要加入 ehcache 的 jar 包及配置文件. 
        -->     
        <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
            <!-- Set a net.sf.ehcache.CacheManager instance here if you already have one.  If not, a new one
                 will be creaed with a default config:
                 <property name="cacheManager" ref="ehCacheManager"/> -->
            <!-- If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
                 a specific Ehcache configuration to be used, specify that here.  If you don't, a default
                 will be used.: -->
            <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/> 
        </bean>
        
        
        <!-- =========================================================
             Shiro Spring-specific integration
             ========================================================= -->
        <!-- Post processor that automatically invokes init() and destroy() methods
             for Spring-configured Shiro objects so you don't have to
             1) specify an init-method and destroy-method attributes for every bean
                definition and
             2) even know which Shiro objects require these methods to be
                called. -->
        <!--  
        4. 配置 LifecycleBeanPostProcessor. 可以自定的来调用配置在 Spring IOC 容器中 shiro bean 的生命周期方法. 
        -->       
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
        <!-- Enable Shiro Annotations for Spring-configured beans.  Only run after
             the lifecycleBeanProcessor has run: -->
        <!--  
        5. 启用 IOC 容器中使用 shiro 的注解. 但必须在配置了 LifecycleBeanPostProcessor 之后才可以使用. 
        -->     
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
              depends-on="lifecycleBeanPostProcessor"/>
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>
        </bean>
    
        <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
             web.xml uses the DelegatingFilterProxy to access this bean.  This allows us
             to wire things with more control as well utilize nice Spring things such as
             PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->
        <!--  
        6. 配置 ShiroFilter. 
        6.1 id 必须和 web.xml 文件中配置的 DelegatingFilterProxy 的 <filter-name> 一致.
                          若不一致, 则会抛出: NoSuchBeanDefinitionException. 因为 Shiro 会来 IOC 容器中查找和 <filter-name> 名字对应的 filter bean.
        -->     
        <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -
             web.xml uses the DelegatingFilterProxy to access this bean.  This allows us
             to wire things with more control as well utilize nice Spring things such as
             PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <property name="loginUrl" value="/login"/>
            <property name="successUrl" value="/list"/>
            <property name="unauthorizedUrl" value="/unauthorized"/>
            <!--  <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>-->
            <!-- The 'filters' property is not necessary since any declared javax.servlet.Filter bean
                 defined will be automatically acquired and available via its beanName in chain
                 definitions, but you can perform overrides or parent/child consolidated configuration
                 here if you like: -->
            <!-- <property name="filters">
                <util:map>
                    <entry key="aName" value-ref="someFilterPojo"/>
                </util:map>
            </property> -->
            <property name="filterChainDefinitions">
                <value>
                    /**/login = anon 
                    /toLogin = anon
                    # everything else requires authentication:
                    /** = authc
                </value>
            </property>
        </bean>
    
        <!--  
        <bean id="filterChainDefinitionMapFactory" class="org.tarena.shiro.factory.FilterChainDefinitionMapFactory">
        </bean>
    
    
        <bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionMapFactory" factory-method="bulidFilterChainDefinitionMap"></bean>
        -->
    </beans>

    ehcache.xml

    <!--
      ~ Licensed to the Apache Software Foundation (ASF) under one
      ~ or more contributor license agreements.  See the NOTICE file
      ~ distributed with this work for additional information
      ~ regarding copyright ownership.  The ASF licenses this file
      ~ to you under the Apache License, Version 2.0 (the
      ~ "License"); you may not use this file except in compliance
      ~ with the License.  You may obtain a copy of the License at
      ~
      ~     http://www.apache.org/licenses/LICENSE-2.0
      ~
      ~ Unless required by applicable law or agreed to in writing,
      ~ software distributed under the License is distributed on an
      ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      ~ KIND, either express or implied.  See the License for the
      ~ specific language governing permissions and limitations
      ~ under the License.
      -->
    
    <!-- EhCache XML configuration file used for Shiro spring sample application -->
    <ehcache>
    
        <!-- Sets the path to the directory where cache .data files are created.
    
    If the path is a Java System Property it is replaced by
    its value in the running VM.
    
    The following properties are translated:
    user.home - User's home directory
    user.dir - User's current working directory
    java.io.tmpdir - Default temp file path -->
        <diskStore path="java.io.tmpdir/shiro-spring-sample"/>
    
    
        <!--Default Cache configuration. These will applied to caches programmatically created through
        the CacheManager.
    
        The following attributes are required:
    
        maxElementsInMemory            - Sets the maximum number of objects that will be created in memory
        eternal                        - Sets whether elements are eternal. If eternal,  timeouts are ignored and the
                                         element is never expired.
        overflowToDisk                 - Sets whether elements can overflow to disk when the in-memory cache
                                         has reached the maxInMemory limit.
    
        The following attributes are optional:
        timeToIdleSeconds              - Sets the time to idle for an element before it expires.
                                         i.e. The maximum amount of time between accesses before an element expires
                                         Is only used if the element is not eternal.
                                         Optional attribute. A value of 0 means that an Element can idle for infinity.
                                         The default value is 0.
        timeToLiveSeconds              - Sets the time to live for an element before it expires.
                                         i.e. The maximum time between creation time and when an element expires.
                                         Is only used if the element is not eternal.
                                         Optional attribute. A value of 0 means that and Element can live for infinity.
                                         The default value is 0.
        diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.
                                         The default value is false.
        diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
                                         is 120 seconds.
        memoryStoreEvictionPolicy      - Policy would be enforced upon reaching the maxElementsInMemory limit. Default
                                         policy is Least Recently Used (specified as LRU). Other policies available -
                                         First In First Out (specified as FIFO) and Less Frequently Used
                                         (specified as LFU)
        -->
    
        <defaultCache
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="false"
                diskPersistent="false"
                diskExpiryThreadIntervalSeconds="120"
                />
    
        <!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session
    expirations explicitly.  If we set it to false and then set corresponding timeToIdle and timeToLive properties,
    ehcache would evict sessions without Shiro's knowledge, which would cause many problems
    (e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"
    Answer - ehcache expired it due to the timeToIdle property set to 120 seconds.)
    
    diskPersistent=true since we want an enterprise session management feature - ability to use sessions after
    even after a JVM restart.  -->
        <cache name="shiro-activeSessionCache"
               maxElementsInMemory="10000"
               eternal="true"
               overflowToDisk="true"
               diskPersistent="true"
               diskExpiryThreadIntervalSeconds="600"/>
    
        <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"
               maxElementsInMemory="100"
               eternal="false"
               timeToLiveSeconds="600"
               overflowToDisk="false"/>
    
    </ehcache>

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="WebApp_ID" version="2.5">
        
        <!-- needed for ContextLoaderListener -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
    
        <!-- Bootstraps the root web application context before servlet initialization -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        
        <!-- 设置servlet编码开始 -->
        <filter>
            <filter-name>Set Character Encoding</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>Set Character Encoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
       
        <!-- The front controller of this Spring Web application, responsible for handling all application requests -->
        <servlet>
            <servlet-name>spring</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!-- Map all requests to the DispatcherServlet for handling -->
        <servlet-mapping>
            <servlet-name>spring</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        
        <!-- Shiro Filter is defined in the spring application context: -->
        <!-- 
        1. 配置  Shiro 的 shiroFilter.  
        2. DelegatingFilterProxy 实际上是 Filter 的一个代理对象. 默认情况下, Spring 会到 IOC 容器中查找和 
        <filter-name> 对应的 filter bean. 也可以通过 targetBeanName 的初始化参数来配置 filter bean 的 id. 
        -->
        <filter>
            <filter-name>shiroFilter</filter-name>
            <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
            <init-param>
                <param-name>targetFilterLifecycle</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
    
        <filter-mapping>
            <filter-name>shiroFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        
    </web-app>
  • 相关阅读:
    a标签点击之后有个虚线边框,怎么去掉
    在ie下,a标签包被img的时候,为什么有个蓝色的边线
    如何让一个变量的值,作为另一个变量的名字
    html 获取宽高
    两个同级div等高布局
    java中IO流异常处理
    连带滑块效果图
    java中File类的使用
    java保留两位小数4种方法
    java日历显示年份、月份
  • 原文地址:https://www.cnblogs.com/xiaoliangup/p/10434372.html
Copyright © 2011-2022 走看看