欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Shiro权限框架与SpringMVC整合

程序员文章站 2023-08-29 18:32:07
1.Shiro整合SpringMVC 我们学习Shiro框架肯定是要应用到Web项目上的,所以我们需要整合Shiro和SpringMVC 整合步骤: 第一步:SpringMVC框架的配置 spring-mvc.xml: spring-context.xml: web.xml: 第二步:Shiro配置 ......

1.shiro整合springmvc

  我们学习shiro框架肯定是要应用到web项目上的,所以我们需要整合shiro和springmvc

整合步骤:

第一步:springmvc框架的配置

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"
    xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
    <!-- 开启mvc注解驱动 -->
    <mvc:annotation-driven/>
    <!-- 放开静态资源的访问 -->
    <mvc:default-servlet-handler/>
   <!-- 配置视图解释器 -->
   <mvc:view-resolvers>
       <mvc:jsp prefix="/web-inf/views/" suffix=".jsp"/>
   </mvc:view-resolvers>
    
</beans>

  spring-context.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:context="http://www.springframework.org/schema/context"
    xsi:schemalocation="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.3.xsd">
    <!-- 注解组件扫描 -->
    <context:component-scan base-package="com.gjs.shiro">
        <!-- 排除不扫描的包 -->
        <context:exclude-filter type="regex" expression="pojo"/>
    </context:component-scan>

</beans>

  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-springmvc-xml</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>
  
  <!-- 配置编码过滤器 -->
    <filter>
        <filter-name>characterencodingfilter</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>
    </filter>
    
    <filter-mapping>
        <filter-name>characterencodingfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 配置前端控制器 -->
    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class>
        <!-- 指定配置类 -->
        <init-param>
            <param-name>contextconfiglocation</param-name>
            <param-value>classpath:spring*.xml</param-value>
        </init-param>
        
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

  

  第二步:shiro配置

  shiro.ini:

[main]
 shirorealm=com.gjs.shiro.realm.shirorealm
 securitymanager.realms=$shirorealm

  shirorealm:

package com.gjs.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.simpleauthenticationinfo;
import org.apache.shiro.authz.authorizationinfo;
import org.apache.shiro.authz.simpleauthorizationinfo;
import org.apache.shiro.realm.authorizingrealm;
import org.apache.shiro.subject.principalcollection;

public class shirorealm extends authorizingrealm{
    /**
     * 校验
     */
    @override
    protected authenticationinfo dogetauthenticationinfo(authenticationtoken token) throws authenticationexception {
        system.out.println("校验");
        if ("admin".equals(token.getprincipal())) {
            return new simpleauthenticationinfo(token.getprincipal(), "123456", this.getname());
        }
        return null;
    }
    /**
     * 授权
     */
    @override
    protected authorizationinfo dogetauthorizationinfo(principalcollection principals) {
        system.out.println("授权");
        simpleauthorizationinfo info = new simpleauthorizationinfo();
        info.addrole("role_admin");
        info.addstringpermission("user:list");
        info.addstringpermission("user:add");
        return info;
    }
}

  第三步:springmvc和shiro整合

  shiro是使用filter拦截请求的,springmvc是使用servlet拦截请求的。而filter的拦截请求优先级别高于servlet,那么我们如何让shiro交给springmvc代理?
  spring提供了一个filter代理类,可以让spring容器代理filter的操作,delegatingfilterproxy。实现了在过滤里面可以调用spring容器的对象,可以让我们把原来配置在web.xml的过滤器配置在spring配置文件里面(原来shiro配置在shiro.ini的配置也可以配置在spring配置文件里)。

  1.在web.xml添加配置:

<!-- 配置代理过滤器,用来代理指定的对象(过滤器) -->
  <filter>
      <filter-name>securityfilter</filter-name>
      <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class>
      <!-- 指定调用容器里面的对象名,如果不指定默认使用filter-name -->
      <init-param>
          <param-name>targetbeanname</param-name>
          <param-value>securityfilter</param-value>
      </init-param>
    <!-- 将目标过滤器的生命周期交给spring容器代理 -->
    <init-param>
        <param-name>targetfilterlifecycle</param-name>
        <param-value>true</param-value>
    </init-param>      
  </filter>
  <filter-mapping>
      <filter-name>securityfilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

  修改后:

<?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-springmvc-xml</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>
  <!-- 配置代理过滤器,用来代理指定的对象(过滤器) -->
  <filter>
      <filter-name>securityfilter</filter-name>
      <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class>
      <!-- 指定调用容器里面的对象名,如果不指定默认使用filter-name -->
      <init-param>
          <param-name>targetbeanname</param-name>
          <param-value>securityfilter</param-value>
      </init-param>
    <!-- 将目标过滤器的生命周期交给spring容器代理 -->
    <init-param>
        <param-name>targetfilterlifecycle</param-name>
        <param-value>true</param-value>
    </init-param>      
  </filter>
  <filter-mapping>
      <filter-name>securityfilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- 配置编码过滤器 -->
    <filter>
        <filter-name>characterencodingfilter</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>
    </filter>
    
    <filter-mapping>
        <filter-name>characterencodingfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 配置前端控制器 -->
    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class>
        <!-- 指定配置类 -->
        <init-param>
            <param-name>contextconfiglocation</param-name>
            <param-value>classpath:spring*.xml</param-value>
        </init-param>
        
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

2.创建spring-shiro.xml配置文件

这个配置文件用来配置shiro的相关配置,并创建shiro过滤器用来给spring的代理过滤器调用
配置完毕我们之前的shiro的ini配置文件就可以删掉了

<?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过滤器给spring的代理过滤器调用  name属性需与web.xml中代理过滤器配置的对象名一致 -->
    <bean name="securityfilter" class="org.apache.shiro.spring.web.shirofilterfactorybean">
        <!-- 指定安全管理器 securitymanager-->
        <property name="securitymanager" ref="securitymanager"/>
        <!-- 登录url -->
        <property name="loginurl" value="/user/login"></property>
        <!-- 配置拦截过滤链 -->
        <property name="filterchaindefinitions">
            <!-- shiro过滤器枚举值在org.apache.shiro.web.filter.mgt.defaultfilter -->
            <value>
                /user/tologin =anon
                /**=authc
            </value>
        </property>
    </bean>
    <!-- 配置securitymanager 安全管理器 -->
    <bean name="securitymanager" class="org.apache.shiro.web.mgt.defaultwebsecuritymanager">
         <!-- 配置securitymanager的realm对象 -->
         <property name="realms" ref="shirorealm"></property>
    </bean>
    <!-- 配置realm -->
    <bean name="shirorealm" class="com.gjs.shiro.realm.shirorealm"/>
</beans>

  3.权限控制器标签的使用

<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
<!-- 以认证跳转到主页 -->
<shiro:authenticated>
   <jsp:forward page="/index"></jsp:forward>
</shiro:authenticated>
<!-- 未认证跳转到登录页面 -->
<shiro:notauthenticated>
   <jsp:forward page="/user/login"></jsp:forward>
</shiro:notauthenticated>
<%@ page language="java" contenttype="text/html; charset=utf-8"
    pageencoding="utf-8"%>   
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>insert title here</title>
</head>
<body>
    <!-- 判断是否有指定的权限,有权限才显示 -->
   <shiro:haspermission name="user:add">
      用户增加
   </shiro:haspermission>
     <shiro:haspermission name="user:edit">
      用户编辑
   </shiro:haspermission>
     <shiro:haspermission name="user:delete">
      用户删除
   </shiro:haspermission>
     <shiro:haspermission name="user:list">
      用户列表
   </shiro:haspermission>
   
</body>
</html>

2.shiro整合springmvc 基于注解

  第一步:配置webx.xml

<!-- 配置代理过滤器,用来代理指定的对象(过滤器) -->
  <filter>
      <filter-name>securityfilter</filter-name>
      <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class>
      <!-- 指定调用容器里面的对象名,如果不指定默认使用filter-name -->
      <init-param>
          <param-name>targetbeanname</param-name>
          <param-value>securityfilter</param-value>
      </init-param>
    <!-- 将目标过滤器的生命周期交给spring容器代理 -->
    <init-param>
        <param-name>targetfilterlifecycle</param-name>
        <param-value>true</param-value>
    </init-param>      
  </filter>
  <filter-mapping>
      <filter-name>securityfilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>

  第二步:配置shiro配置类

package com.gjs.rbac.config;

import java.util.linkedhashmap;
import java.util.map;

import org.apache.shiro.mgt.securitymanager;
import org.apache.shiro.spring.web.shirofilterfactorybean;
import org.apache.shiro.web.mgt.defaultwebsecuritymanager;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;

import com.gjs.rbac.realms.shirorealm;

@configuration
public class shiroconfig {
    
    //1.配置shiro过滤器  用于给spring的代理过滤器调用
    @bean("securityfilter")
    public object getshirofilterfactorybean() {
        shirofilterfactorybean factorybean = new shirofilterfactorybean();
        factorybean.setsecuritymanager(this.getsecuritymanager());
        factorybean.setsuccessurl("/toindex");
        factorybean.setloginurl("/user/login");
        
        //定义过滤器链,使用linkedhashmap是因为它是有顺序的(添加顺序)
        map<string, string> filterchain =new linkedhashmap<>();
        filterchain.put("/user/tologin", "anon");
        filterchain.put("/**", "authc");
        factorybean.setfilterchaindefinitionmap(filterchain);
        try {
            return factorybean.getobject();
        } catch (exception e) {
            e.printstacktrace();
        }
        return null;
    }
    
    //2.创建securitymanager
    @bean
    public securitymanager getsecuritymanager() {
        defaultwebsecuritymanager securitymanager = new defaultwebsecuritymanager();
        securitymanager.setrealm(this.getshirorealm());
        return securitymanager;
    }
    //创建自定义的realm
    @bean
    public shirorealm getshirorealm() {
        shirorealm shirorealm = new shirorealm();
        return shirorealm;
    }
}