1. Shiro整合SpringMVC基于XML
1.1. 说明
上面的知识,我们已经了解Shiro的权限授权、权限校验、Md5的加密密码的配置。
但是,我们的需求将Shiro框架用到Web项目。
所以,我们需要使用Shiro整合SpringMVC使用!!!
1.2. 整合步骤说明
1. 配置SpringMVC框架
2. 配置Shiro框架
3. 整合SpringMVC与Shiro
1.3. 整合步骤
1.3.1. 第一部分:SpringMVC框架的配置
1.3.1.1. 步骤说明
1. 导入依赖的Jar包
2. 构建一个请求页面
3. 创建业务控制器
4. 配置web.xml的核心控制器
5. 创建配置文件
6. 构建一个返回页面
1.3.1.2. 第一步:导入依赖的Jar包

1.3.1.3. 第二步:构建一个请求页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="${pageContext.request.contextPath }/admin/addAdmin">addAdmin</a>
</body>
</html>
1.3.1.4. 第三步:创建业务控制器
package cn.gzsxt.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.annotation.SessionScope;
@Controller
@SessionScope
@RequestMapping(value="admin")
public class AdminController {
@RequestMapping(value="/addAdmin")
public String addAdmin(){
System.out.println("=增加管理员=");
return "/index.jsp";
}
}
1.3.1.5. 第四步:配置web.xml的核心控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>shiro-demo-08-springmvc</display-name>
<!-- 配置核心控制器。拦截器所有的请求 -->
<servlet>
<servlet-name>dispatcherServlet</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>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
1.3.1.6. 第五步:创建配置文件
--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:annotation-driven />
<!-- 放开静态资源访问 -->
<mvc:default-servlet-handler/>
</beans>
--Spring容器配置文件,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="cn.gzsxt" />
</beans>
1.3.2. 第二部分:Shiro框架的配置
1.3.2.1. 配置步骤说明
1. 导入依赖的Jar包
2. 创建Shiro.ini配置文件
3. 创建一个入口测试类
4. 创建一个Realm
1.3.2.2. 第一步:导入依赖的Jar包

1.3.2.3. 第二步:创建Shiro.ini配置文件
[users]
admin = 123456,adminRole
[roles]
adminRole = admin:list,admin:add,admin:delete,admin:edit
1.3.2.4. 第三步:创建一个入口测试类
package cn.gzsxt.shiro.test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
public class ShiroTest {
public static void main(String[] args) {
//第一步:加载ini配置文件,获得SecurityManagerFactory对象
IniSecurityManagerFactory factory=new IniSecurityManagerFactory("classpath:shiro.ini");
//第二步:获得SecurityManager对象
SecurityManager securityManager = factory.createInstance();
//第三步:获得Subject身份对象
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
//第四步:构建一个身份信息对象(Token)
UsernamePasswordToken token=new UsernamePasswordToken("admin","123456");
//第五步:login操作。校验权限
Subject resultSubject = securityManager.login(subject, token);
//第六步:校验是否成功
boolean isAuth= resultSubject.isAuthenticated();
System.out.println(isAuth);
}
}
1.3.2.5. 第四步:创建一个Realm
--修改配置文件
#[users]
# admin = 123456,adminRole
#[roles]
# adminRole = admin:list,admin:add,admin:delete,admin:edit
[main]
myRealm = cn.gzsxt.realm.MyRealm
securityManager.realms=$myRealm
--MyRealm类
package cn.gzsxt.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.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("=权限校验=");
try {
if (token.getPrincipal().equals("admin")) {
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(), "123456",
this.getName());
return info;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
info.addRole("role_admin");
info.addStringPermission("user:add");
info.addStringPermission("user:list");
//info.addStringPermission("user:edit");
return info;
}
}
1.3.2.6. 第五步:测试结果
--运行ShiroTest测试类,结果为:

1.3.3. 第三部分:SpringMVC整合Shiro
1.3.3.1. 说明
1. 权限控制是对谁的控制?,就是对url访问权限的控制。
2. Filter的拦截请求优先级别高于Servlet。而Shiro是使用Filter拦截的,SpringMVC是使用Servlet拦截请求的。那么我们如何让Shiro交给SpringMVC代理呢?
答:Spring提供了一个Filter代理类,可以让Spring容器代理Filter的操作,DelegatingFilterProxy。实现了在过滤里面可以调用Spring容器的对象,把我们原来配置在web.xml的过滤器配置在Spring配置文件里面。
1.3.3.2. Shiro提供的过滤器说明
在org.apache.shiro.web.filter.mgt.DefaultFilter枚举里面定义可以使用的过滤器以及对于的枚举值

anon : 匿名过滤器,该过滤器的作用就是用于配置不需要授权就可以直接访问的路径。
authc: 校验过滤器,该过滤器的作用就是用于必须经过校验才可以访问的路径(url)
logout: 注销过滤器, 该过滤器的作用就是用于注销退出登录。
perms:权限验证过滤器,用于权限验证的
1.3.3.3. 配置步骤说明
1. 在web.xml配置过滤器代理类DelegatingFilterProxy,让Filter交个Spring容器代理
2. 创建一个spring-shiro.xml配置文件
1.3.3.4. 第一步:配置web.xml
<filter>
<filter-name>securityFilterBean</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 将生命周期交给Spring代理 -->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>securityFilterBean</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1.3.3.5. 第二步:创建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">
<!-- 配置拦截器调用的对象 注意事项:bean的名字必须要和web.xml的DelegatingFilterProxy的过滤的name属性一一对应。 -->
<bean name="securityFilterBean" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 指定跳转到校验不成功的路径 ,不指定会跳转上一次访问菜单页面 -->
<!-- <property name="unauthorizedUrl" value="/undo"></property> -->
<!-- 指定依赖的securityManager对象 -->
<property name="securityManager" ref="securityManager"></property>
<!-- 指定 登录请求的路径 -->
<property name="loginUrl" value="/admin/loginAdmin"></property>
<!-- 登录成功跳转的路径 -->
<property name="successUrl" value="/index"></property>
<!-- 用于指定执行的过滤器链 ,配置多个过滤器连接对的url -->
<property name="filterChainDefinitions">
<value>
<!-- 指定url与过滤器的关系 -->
<!-- 所有的路径都要拦截 -->
/admin/toLogin = anon
/** = authc
</value>
</property>
</bean>
<!-- 2.指定securityManager的对象 -->
<bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm" />
</bean>
<!-- 3.创建一个Realm对象 -->
<bean name="myRealm" class="cn.gzsxt.realm.MyRealm"></bean>
<!-- 4.Spring容器对shiro生命周期的管理 ,基于注解权限拦截需要配置-->
<bean name="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
</beans>
1.3.3.6. 第三步:权限控制器标签的使用
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
主页 <a href="${pageContext.request.contextPath }/logout">退出</a><br/>
<shiro:hasPermission name="user:list">
<!-- 如果有user:list权限才显示 用户列表 -->
<a href="#"> 用户列表</a><br/>
</shiro:hasPermission>
<shiro:hasPermission name="user:add">
<!-- 如果有user:add权限才显示 用户增加 -->
<a href="#"> 用户增加</a><br/>
</shiro:hasPermission>
<shiro:hasPermission name="user:edit">
<!-- 如果有user:edit权限才显示 用户编辑 -->
<a href="#"> 用户编辑</a><br/>
</shiro:hasPermission>
<shiro:hasPermission name="user:delete">
<!-- 如果有user:delete权限才显示 用户删除 -->
<a href="#"> 用户删除</a><br/>
</shiro:hasPermission>
</body>
</html>
2. Shiro整合SpringMVC基于注解
2.1. 配置流程说明
2.1.1. 第一步:配置webx.xml
<filter>
<filter-name>securityFilterBean</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<!-- 将生命周期交给Spring代理 -->
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>securityFilterBean</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.1.2. 第二步:配置Shiro配置类
package cn.gzsxt.config;
import java.util.LinkedHashMap;
import java.util.Map;
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 cn.gzsxt.realm.ShiroRealm;
@Configuration
public class ShiroConfig {
//1.配置securityFilterBean对象
@Bean(name="securityFilter")
public Object getShiroFilterFactory() {
ShiroFilterFactoryBean factory=new ShiroFilterFactoryBean();
//设置属性
factory.setLoginUrl("/login");
factory.setSuccessUrl("/index");
factory.setSecurityManager(this.getSecurityManager());
//基于配置的权限过滤器,顺序执行,所以使用LinkedHashMap
Map<String, String> filterChainDefinition=new LinkedHashMap<>();
filterChainDefinition.put("/**", "authc");
factory.setFilterChainDefinitionMap(filterChainDefinition);
Object securityFilter=null;
try {
securityFilter = factory.getObject();
} catch (Exception e) {
e.printStackTrace();
}
return securityFilter;
}
//2.获得securityManager对象
@Bean(name="securityManager")
public DefaultWebSecurityManager getSecurityManager() {
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
//设置需要的realm对象
securityManager.setRealm(this.getRealm());
return securityManager;
}
//3.配置realm对象
@Bean
public ShiroRealm getRealm(){
ShiroRealm realm=new ShiroRealm();
return realm;
}
}