美文网首页
Spring 集成 Shiro

Spring 集成 Shiro

作者: tingshuo123 | 来源:发表于2018-09-06 12:56 被阅读20次

    项目结构

    image.png

    pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.project.tingshuo</groupId>
        <artifactId>Shiro-2</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
    
    
        <properties>
            <webVersion>3.0</webVersion>
            <!-- failOnMissingWebXml:true告诉maven项目,web.xml可以缺失 -->
            <failOnMissingWebXml>false</failOnMissingWebXml>
            <!-- maven默认使用gbk编码,设置为utf-8 -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!-- 先定义jar包版本 -->
            <spring.version>4.2.8.RELEASE</spring.version>
        </properties>
    
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
        <dependencies>
    
            <!-- Shiro -->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-web</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.3.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-ehcache</artifactId>
                <version>1.4.0</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-nop</artifactId>
                <version>1.7.2</version>
            </dependency>
    
    
            <!-- spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!-- ehcache -->
            <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache-core</artifactId>
                <version>2.6.11</version>
            </dependency>
    
        </dependencies>
    </project>
    

    jsp:
    测试权限是否成功用的,随便写点内容就可以了。

    spring 配置

    <?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 核心配置 -->
        <!-- 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="realm" ref="jdbcRealm" />
        </bean>
    
        <!-- 2. 配置EacheManager 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:shiro-ehcache.xml" />
        </bean>
    
        <!-- 
        3. 配置Realm
        3.1 实现了 org.apache.shiro.realm.Realm 接口的 bean
         -->
        <bean id="jdbcRealm"
            class="com.project.shiro.realm.ShiroRealm">
        </bean>
    
        <!-- 
        4. 配置 LifecycleBeanPostProcessor:可以自定义的调用配置在 Spring IOC 容器中 Shiro bean 的生命周期方法
         -->
        <bean id="lifecycleBeanPostProcessor"
            class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
    
        <!-- 
        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>
    
        
    
        <!-- 
        6. 配置 ShiroFilter
        6.1 id 需要和 web.xml 文件中配置的 DelegatingFilterProxy 的 filter-name 一致
        6.2 
         -->
        <bean id="shiroFilter"
            class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <!-- 登录页面 -->
            <property name="loginUrl" value="/login.jsp" />
            <!-- 登录成功页面 -->
            <property name="successUrl" value="/index.jsp" />
            <!-- 没有权限的页面 -->
            <property name="unauthorizedUrl" value="/unauthorized.jsp" />
            
            <!-- 
            配置受保护的页面
            以及访问页面需要的权限
            anon:可以被匿名访问
            authc:认证(登录)后才可以访问
             -->
            <property name="filterChainDefinitions">
                <value>
                    /login.jsp = anon
                    # everything else requires authentication:
                    /** = authc
                </value>
            </property>
        </bean>
    
    </beans>
    

    springMVC 配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    
    <!--    
    <bean
            class="org.springframework.web.servlet.view.InternalResourceView">
            <property name="prefix" value="/"></property>
            <property name="suffix" value=".jsp></property>
        </bean> -->
        
        <!-- 扫描包 -->
        <context:component-scan base-package="com.project.shiro"></context:component-scan>
        <!-- 开启注解 -->
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
        <mvc:default-servlet-handler/>
    </beans>
    

    Eacahe 缓存配置

    <!--
      ~ 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="D:\ehcache"/>
    
    
        <!--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"
        version="2.5">
        <display-name>shiro-2</display-name>
        <welcome-file-list>
            <welcome-file>index.html</welcome-file>
            <welcome-file>index.htm</welcome-file>
            <welcome-file>index.jsp</welcome-file>
            <welcome-file>default.html</welcome-file>
            <welcome-file>default.htm</welcome-file>
            <welcome-file>default.jsp</welcome-file>
        </welcome-file-list>
    
        <!-- 配置Spring -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applictionContext.xml</param-value>
        </context-param>
    
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    
        <!-- 配置SpringMVC -->
        <servlet>
            <servlet-name>springDispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>springDispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        
        <!-- 配置Shiro -->
        <filter>
            <!-- filter-name的值需要和 applicationContext 中 ShiroFilterFactoryBean 的id一致 -->
            <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>
    

    ShiroRealm配置:

    package com.project.shiro.realm;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.LockedAccountException;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.crypto.hash.SimpleHashRequest;
    import org.apache.shiro.realm.AuthenticatingRealm;
    import org.apache.shiro.util.ByteSource;
    
    public class ShiroRealm extends AuthenticatingRealm{
    
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            
            System.out.println("[FirstRealm] doGetAuthenticationInfo");
            
            // 1. 将 token 转换为 UsernamePasswordToken
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
            // 2. 获取 账号 密码
            String username = upToken.getUsername();
            
            // 3. 从数据库中获取对应用户记录
            System.out.println("从数据库中获取username:" + username + "对应用户信息");
            
            // 4. 用户不存在可以抛出 UnknownAccountException 异常
            if ("unknown".equals(username)) {
                throw new UnknownAccountException("用户不存在");
            }
            
            // 5. 用户被锁定 可以抛 LockedAccountException 异常
            if ("monster".equals(username)) {
                throw new LockedAccountException("用户被锁定");
            }
            // 6. 构建 AuthenticationInfo
            // 1). principal: 认证的实体信息
            // 2). credentials:密码
            // 3). realmName:当前 realm 对象的 name
            // 4). 盐值
            Object principal = username;
            Object hashedCredentials = "1c8fd15d4a4bf0fcd3dca934c4001eb1";  // Shiro 会自动验证密码
            String realmName = this.getName();
            ByteSource credentialsSalt = ByteSource.Util.bytes(username);
            
            System.out.println(principal);
            
            return new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
        }
    
    多Realm配置

    有自定义的两个Realm类,com.project.shiro.realm.ShiroRealmcom.project.shiro.realm.SecondRealm
    applicationContext.xml 中配置多 realm

        <!-- 
        3. 配置Realm
        3.1 实现了 org.apache.shiro.realm.Realm 接口的 bean
         -->
        <bean id="jdbcRealm" class="com.project.shiro.realm.ShiroRealm">
            <property name="credentialsMatcher">
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <!-- 指定加密算法 -->
                    <property name="hashAlgorithmName" value="MD5"></property>
                    <!-- 指定加密次数 -->
                    <property name="hashIterations" value="1"></property>
                </bean>
            </property>
        </bean>
        
        <bean id="secondRealm" class="com.project.shiro.realm.SecondRealm">
            <property name="credentialsMatcher">
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <!-- 指定加密算法 -->
                    <property name="hashAlgorithmName" value="SHA1"></property>
                    <!-- 指定加密次数 -->
                    <property name="hashIterations" value="1"></property>
                </bean>
            </property>
        </bean>
    

    第一种方法:在 authenticator 配置

        <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
            <!-- 配置多realm -->
            <property name="realms">
                <list>
                    <ref bean="jdbcRealm"/>
                    <ref bean="secondRealm"/>
                </list>
            </property>
        </bean>
    

    第二种方法:在 securityManager 配置

        <!-- Shiro 核心配置 -->
        <!-- 1. 配置 SecurityManager -->
        <bean id="securityManager"
            class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <property name="cacheManager" ref="cacheManager" />
            <property name="authenticator" ref="authenticator" />
            
            <property name="realms">
                <list>
                    <ref bean="jdbcRealm"/>
                    <ref bean="secondRealm"/>
                </list>
            </property>
        </bean>
    

    以上配置都是在applictionContext.xml中,两个方式选择一个即可,推荐使用后者。

    密码加盐加密配置

    Realm:
    使用SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName); 构造器

    package com.project.shiro.realm;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.LockedAccountException;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.crypto.hash.SimpleHash;
    import org.apache.shiro.realm.AuthenticatingRealm;
    import org.apache.shiro.util.ByteSource;
    
    public class SecondRealm extends AuthenticatingRealm{
    
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            
            System.out.println("[SecondReaml] doGetAuthenticationInfo");
            
            // 1. 将 token 转换为 UsernamePasswordToken
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
            // 2. 获取 账号 密码
            String username = upToken.getUsername();
            
            // 3. 从数据库中获取对应用户记录
            System.out.println("从数据库中获取username:" + username + "对应用户信息");
            
            // 4. 用户不存在可以抛出 UnknownAccountException 异常
            if ("unknown".equals(username)) {
                throw new UnknownAccountException("用户不存在");
            }
            
            // 5. 用户被锁定 可以抛 LockedAccountException 异常
            if ("monster".equals(username)) {
                throw new LockedAccountException("用户被锁定");
            }
            // 6. 构建 AuthenticationInfo
            // 1). principal: 认证的实体信息
            // 2). credentials:密码
            // 3). realmName:当前 realm 对象的 name
            // 4). 盐值
            Object principal = username;
            Object hashedCredentials = "e0c9c5b5b4a1c22f8f183245e0e1cf9deccdebba";  // Shiro 会自动验证密码
            String realmName = this.getName();
            ByteSource credentialsSalt = ByteSource.Util.bytes(username);
            
            System.out.println(principal);
            
            return new SimpleAuthenticationInfo(principal, hashedCredentials, credentialsSalt, realmName);
        }
    }
    

    applicationContext.xml 中的Realm配置:

        <bean id="jdbcRealm" class="com.project.shiro.realm.ShiroRealm">
            <property name="credentialsMatcher">
                <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                    <!-- 指定加密算法 -->
                    <property name="hashAlgorithmName" value="MD5"></property>
                    <!-- 指定加密次数 -->
                    <property name="hashIterations" value="1"></property>
                </bean>
            </property>
        </bean>
    
    认证策略
    • FirstSuccessfulStrategy:通过有一个Realm验证即通过验证,会返回第一个通过的Realm认证信息
    • AtLeastOneSuccessfulStrategy:同样一个通过即可,但是这个会返回所有Realm 身份验证成功的认证信息
    • AllSuccessfulStrategy:这个比较严厉,要通过所有的 Realm 验证才算成功,且返回所有的Realm 的认证信息

    默认使用的是 AtLeastOneSuccessfulStrategy 验证策略;

    通过 applicationContext 改变验证策略

        <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
            <!-- 配置多realm -->
            <property name="realms">
                <list>
                    <ref bean="jdbcRealm"/>
                    <ref bean="secondRealm"/>
                </list>
            </property>
            <!-- 配置认证策略 -->
            <property name="authenticationStrategy">
                <bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean>
            </property>
        </bean>
    

    页面权限配置

    applicatoinContext 中的配置

        <!-- 
        6. 配置 ShiroFilter
        6.1 id 需要和 web.xml 文件中配置的 DelegatingFilterProxy 的 filter-name 一致
        6.2 
         -->
        <bean id="shiroFilter"
            class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager" />
            <!-- 登录页面 -->
            <property name="loginUrl" value="/login.jsp" />
            <!-- 登录成功页面 -->
            <property name="successUrl" value="/index.jsp" />
            <!-- 没有权限的页面 -->
            <property name="unauthorizedUrl" value="/unauthorized.jsp" />
            
            <!-- 配置页面权限管理 -->
            <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>
            
            <!-- 
            配置受保护的页面
            以及访问页面需要的权限
            anon:可以被匿名访问
            authc:认证(登录)后才可以访问
             -->
            <!-- <property name="filterChainDefinitions">
                <value>
                    /login.jsp = anon
                    /login.action = anon
                    
                    /user.jsp = roles[user]
                    /admin.jsp = roles[admin]
                    
                    # everything else requires authentication:
                    /** = authc
                </value>
            </property> -->
        </bean>
        
        <!-- 配置一个bean, 本质是一个Map, 通过实例工厂方法的方式 -->
        <bean id="filterChainDefinitionMap"
            factory-bean="filterChainDefinitionMapBulider" factory-method="buildFilterrChainDefinitionMap"></bean>
        
        <bean id="filterChainDefinitionMapBulider" 
            class="com.project.shiro.factory.FilterChainDefinitionMapBulider"></bean>
    

    FilterChainDefinitionMapBulider:

    package com.project.shiro.factory;
    
    import java.util.LinkedHashMap;
    
    /**
     * 页面访问权限配置
     *
     */
    public class FilterChainDefinitionMapBulider {
        
        public LinkedHashMap<String, String> buildFilterrChainDefinitionMap() {
            
            LinkedHashMap<String, String> map = new LinkedHashMap<>();
            
            // 从数据库中读取,然后放入map中
            map.put("/login.jsp", "anon");
            map.put("/login.action", "anon");
            map.put("/**", "authc");
            
            return map;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Spring 集成 Shiro

          本文链接:https://www.haomeiwen.com/subject/tpfxgftx.html