zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Shiro(一):Shiro集成Spring(xml配置方式)

Spring集成配置XML 方式 shiro
2023-09-11 14:20:19 时间

根据尚硅谷Shiro视频学习Shiro集成Spring、授权、认证、密码比对、多Realms、会话管理、缓存、记住我相关功能实现。

这边文章主要讲的是Shiro集成Spring。实现过程如下:

一、创建 spring+spring mvc 项目

使用Myeclipse创建 spring+spring mvc 项目 文里已经详细介绍了,这里不再累赘。

二、shiro集成spring

• Shiro 提供了与 Web 集成的支持,其通过一个ShiroFilter 入口来拦截需要安全控制的URL,然后进行相应的控制
• ShiroFilter 类似于如 Strut2/SpringMVC 这种web 框架的前端控制器,是安全控制的入口点,其负责读取配置(如ini 配置文件),然后判断URL 是否需要登录/权限等工作。
在这里插入图片描述

1.引入 shiro的jar 包

下载shiro必要的jar,并把如下四个.jar文件复制到项目lib文件夹下:
在这里插入图片描述

下载地址https://github.com/katie1221/installation-package下的CodeTools-shiro.rar

2.配置shiro

shiro官网下载shiro(以1.3.2为例),
在这里插入图片描述

2.1 在web.xml中配置shiroFilter过滤器

下载完成,解压打开,打开如下目录下的web.xml文件,并其中的shiroFilter过滤器复制粘贴到自己项目中的web.xml中
在这里插入图片描述
在这里插入图片描述

web.xml:

 <!-- 
 3.配置shiroFilter
 3.1 DelegatingFilterProxy实际上是Filter的一个代理对象。默认情况下,spring 会到IOC容器中查找
     	和 <filter-name>对应的filter bean。也可以通过targetBeanName的初始化参数来设置filter bean 的id。
 --> 
   <!-- Shiro Filter is defined in the spring application context: -->
    <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>

2.2 在spring配置文件applicationContext.xml里配置shiro

把如下图目录中的applicationContext.xml里面的内容
在这里插入图片描述
复制粘贴到项目中的applicationContext.xml里:
在这里插入图片描述
然后进行如下修改:

2.2.1.配置securityManager

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="cacheManager" ref="cacheManager"/>
        <property name="realm" ref="jdbcRealm"/>
    </bean>

2.2.2.配置 cacheManager

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

ehcache.xml:hibernate jar中有,直接拿过来用。
hibernate下载地址:https://blog.csdn.net/qq_26321411/article/details/79310423
在这里插入图片描述

2.2.3.配置自定义Realm

新建ShiroRealm类,实现org.apache.shiro.realm.Realm 接口
在这里插入图片描述

<!-- 
      3.配置自定义Realm
        3.1直接配置实现了org.apache.shiro.realm.Realm接口的bean
     -->
    <bean id="jdbcRealm" class="com.example.shiro.realms.ShiroRealm"></bean>

2.2.4.配置 LifecycleBeanPostProcessor

<!-- 
    4.配置 LifecycleBeanPostProcessor。可以自动的来调用配置在Spring IOC 容器中shiro bean的生命周期方法
    -->     
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

2.2.5.配置注解

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

2.2.6.配置ShiroFilter

   <!-- 
    6.配置ShiroFilter
      6.1 id必须和web.xml文件中配置的DelegatingFilterProxy的<filter-name>一致。
      若不一致,则会抛出:NoSuchBeanDefinitionException。因为Shiro会来 IOC容器中查找和<filter-name>名字对应的filter bean。	
     -->
    <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"/>
        <!-- 
                                配置哪些页面需要受保护。
                                以及访问这些页面需要的权限
           1)  anon 可以匿名访问
           2)  authc 必须认证(即登录)  之后才可以访问    
         -->
        <property name="filterChainDefinitions">
            <value>
                /login = anon
                # everything else requires authentication:
                /** = authc
            </value>
        </property>
    </bean>

2.3 完整的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"
	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"/>
        <property name="realm" ref="jdbcRealm"/>
    </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>

    <!-- Used by the SecurityManager to access security data (users, roles, etc).
         Many other realm implementations can be used too (PropertiesRealm,
         LdapRealm, etc. -->
    <!-- 
      3.配置Realm
        3.1直接配置实现了org.apache.shiro.realm.Realm接口的bean
     -->
    <bean id="jdbcRealm" class="com.example.shiro.realms.ShiroRealm"></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。
     -->
    <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"/>
        <!-- 
                                配置哪些页面需要受保护。
                                以及访问这些页面需要的权限
           1)  anon 可以匿名访问
           2)  authc 必须认证(即登录)  之后才可以访问    
         -->
        <property name="filterChainDefinitions">
            <value>
                /login = anon
                # everything else requires authentication:
                /** = authc
            </value>
        </property>
    </bean>

</beans>

3.测试

配置完成。创建controller,配置访问连接,进行测试

HelloController :

package com.example.shiro.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

@RestController
public class HelloController {

	/**
	 * 进入用户页面
	 * @return
	 */
	@RequestMapping("/index")
	public ModelAndView index(){
		return new ModelAndView("user");
	}
	
	/**
	 * 进入login页面
	 * @return
	 */
	@RequestMapping("/login")
	public ModelAndView login(){
		return new ModelAndView("login");
	}
	
	/**
	 * 进入list页面
	 * @return
	 */
	@RequestMapping("/list")
	public ModelAndView list(){
		return new ModelAndView("list");
	}
	
	/**
	 * 进入unauthorized页面
	 * @return
	 */
	@RequestMapping("/unauthorized")
	public ModelAndView unauthorized(){
		return new ModelAndView("unauthorized");
	}
}

在浏览器网址中输入http://localhost/shiro1/index,进行测试,进入登录页面,测试成功(shiro配置中login是匿名访问,其他需要认证才可以访问)
在这里插入图片描述

三、applicationContext.xml文件中的ShiroFilter 的 id必须和web.xml文件中配置的DelegatingFilterProxy的一致的原因

原因如下:若不一致,项目启动时则会抛出:NoSuchBeanDefinitionException异常。因为Shiro会来 IOC容器中查找和名字对应的filter bean,找不到就是抛出对应的异常。
在这里插入图片描述
启动项目发现报异常了,验证上面的结论:applicationContext.xml文件中的ShiroFilter 的 id必须和web.xml文件中配置的DelegatingFilterProxy的一致
在这里插入图片描述