SpringMVC整合Shiro
第一部分:SpringMVC框架的配置
配置步骤说明
(1)导入依赖的Jar包
(2)构建一个请求的界面
(3)创建业务控制器
(4)配置 web.xml 的核心控制器
(5)创建配置文件
(6)构建一个返回界面
第一步:导入依赖的Jar包
第二步:构建一个请求界面
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>Insert title here</title> 8 </head> 9 <body> 10 <a href="${pageContext.request.contextPath }/admin/addAdmin">addAdmin</a> 11 </body> 12 </html>
第三步:创建业务控制器
1 package cn.mgy.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.context.annotation.SessionScope; 6 7 @Controller 8 @SessionScope 9 @RequestMapping(value="admin") 10 public class AdminController { 11 12 @RequestMapping(value="/addAdmin") 13 public String addAdmin(){ 14 System.out.println("=增加管理员="); 15 return "/index.jsp"; 16 } 17 18 }
第四步:配置 web.xml 的核心控制器
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 5 id="WebApp_ID" version="3.1"> 6 <display-name>shiro-demo-08-springmvc</display-name> 7 8 <!-- 配置核心控制器。拦截器所有的请求 --> 9 <servlet> 10 <servlet-name>dispatcherServlet</servlet-name> 11 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 12 <!-- 指定配置文件的路径 --> 13 <init-param> 14 <param-name>contextConfigLocation</param-name> 15 <param-value>classpath:spring-*.xml</param-value> 16 </init-param> 17 <!-- 配置启动的时候就创建对象 --> 18 <load-on-startup>1</load-on-startup> 19 </servlet> 20 <servlet-mapping> 21 <servlet-name>dispatcherServlet</servlet-name> 22 <url-pattern>/</url-pattern> 23 </servlet-mapping> 24 25 <welcome-file-list> 26 <welcome-file>index.jsp</welcome-file> 27 </welcome-file-list> 28 </web-app>
第五步:创建配置文件
---- SpringMVC 配置文件, spring-mvc.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> 7 8 <!-- 启动默认注解支持 --> 9 <mvc:annotation-driven /> 10 <!-- 放开静态资源访问 --> 11 <mvc:default-servlet-handler/> 12 13 </beans>
---- Spring 容器配置文件,spring-context.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> 7 8 <!-- 扫描组件配置 --> 9 <context:component-scan base-package="cn.mgy" /> 10 </beans>
第二部分:Shiro 框架的配置
配置步骤说明:
(1)导入依赖的 Jar 包
(2)创建 Shiro.ini 配置文件
(3)创建一个入口测试类
(4)创建一个 Realm
第一步:导入依赖的 Jar 包
第二步:创建 Shiro.ini 配置文件
[users]
admin = 123456,adminRole
[roles]
adminRole = admin:list,admin:add,admin:delete,admin:edit
第三步:创建一个入口测试类
1 package cn.mgy.shiro.test; 2 3 import org.apache.shiro.SecurityUtils; 4 import org.apache.shiro.authc.UsernamePasswordToken; 5 import org.apache.shiro.config.IniSecurityManagerFactory; 6 import org.apache.shiro.mgt.SecurityManager; 7 import org.apache.shiro.subject.Subject; 8 9 public class ShiroTest { 10 11 12 public static void main(String[] args) { 13 //第一步:加载ini配置文件,获得SecurityManagerFactory对象 14 IniSecurityManagerFactory factory=new IniSecurityManagerFactory("classpath:shiro.ini"); 15 //第二步:获得SecurityManager对象 16 SecurityManager securityManager = factory.createInstance(); 17 //第三步:获得Subject身份对象 18 SecurityUtils.setSecurityManager(securityManager); 19 Subject subject = SecurityUtils.getSubject(); 20 21 //第四步:构建一个身份信息对象(Token) 22 UsernamePasswordToken token=new UsernamePasswordToken("admin","123456"); 23 24 //第五步:login操作。校验权限 25 Subject resultSubject = securityManager.login(subject, token); 26 27 //第六步:校验是否成功 28 boolean isAuth= resultSubject.isAuthenticated(); 29 System.out.println(isAuth); 30 31 } 32 33 }
第四步:创建一个 Realm
---- 修改配置文件 shiro.ini
#[users]
# admin = 123456,adminRole
#[roles]
# adminRole = admin:list,admin:add,admin:delete,admin:edit
[main]
myRealm = cn.mgy.realm.MyRealm
securityManager.realms=$myRealm
---- MyRealm 类
1 package cn.mgy.realm; 2 3 import org.apache.shiro.authc.AuthenticationException; 4 import org.apache.shiro.authc.AuthenticationInfo; 5 import org.apache.shiro.authc.AuthenticationToken; 6 import org.apache.shiro.authc.SimpleAuthenticationInfo; 7 import org.apache.shiro.authz.AuthorizationInfo; 8 import org.apache.shiro.realm.AuthorizingRealm; 9 import org.apache.shiro.subject.PrincipalCollection; 10 11 public class MyRealm extends AuthorizingRealm { 12 13 @Override 14 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 15 System.out.println("=权限校验="); 16 try { 17 if (token.getPrincipal().equals("admin")) { 18 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(), "123456", 19 this.getName()); 20 return info; 21 } 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 26 return null; 27 } 28 29 @Override 30 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 31 32 return null; 33 } 34 35 }
第五步:测试结果
---- 运行 ShiroTest 测试类,结果为:
第三部分:SpringMVC 整合 Shiro (基于 XML)
1、说明
(1)权限控制是对谁的控制? 就是对 url 访问权限的控制
(2)Filter 的优先级别高于 Servlet。而 Shiro 是使用 Filter 拦截的,SpringMVC 是使用 Servlet 拦截请求的。那么如何让 Shiro 交给 SpringMVC 代理呢?
答:Spring 提供了一个 Filter 代理类,可以让 Spring 容器代理 Filter 的操作,该 Filter 代理是 DelegatingFilterProxy。实现了在过滤里面可以调用 Spring 容器的对象,把原来配置在 web.xml 的过滤器配置在 Spring 配置文件里面。
2、Shiro 提供的过滤器说明
在 org.apache.shiro.web.filter.mgt.DefaultFilter 枚举里面定义可以使用的过滤器以及对应的枚举值
anon:匿名过滤器,该过滤器的作用就是用于配置不需要授权就可以直接访问的路径
authc:校验过滤器,该过滤器的作用就是用于必须经过校验才可以访问的路径(url)
logout:注销过滤器,该过滤器的作用就是用于注销退出登录
perms:权限验证过滤器,用于权限验证的
3、配置步骤说明
(1)在 web.xml 配置过滤器代理类 DelegatingFilterProxy,让 Filter 交给 Spring 容器代理
(2)创建一个 spring-shiro.xml 配置文件
第一步:配置 web.xml
1 <filter> 2 <filter-name>securityFilterBean</filter-name> 3 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 4 <!-- 将生命周期交给Spring代理 --> 5 <init-param> 6 <param-name>targetFilterLifecycle</param-name> 7 <param-value>true</param-value> 8 </init-param> 9 </filter> 10 <filter-mapping> 11 <filter-name>securityFilterBean</filter-name> 12 <url-pattern>/*</url-pattern> 13 </filter-mapping>
第二步:创建一个 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"> <!-- 配置拦截器调用的对象 注意事项: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.mgy.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>
第三部分:SpringMVC 整合 Shiro(基于注解)
第一步:配置 web.xml
1 <filter> 2 <filter-name>securityFilterBean</filter-name> 3 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 4 <!-- 将生命周期交给Spring代理 --> 5 <init-param> 6 <param-name>targetFilterLifecycle</param-name> 7 <param-value>true</param-value> 8 </init-param> 9 </filter> 10 <filter-mapping> 11 <filter-name>securityFilterBean</filter-name> 12 <url-pattern>/*</url-pattern> 13 </filter-mapping>
第二步:配置 Shiro 配置类
1 package cn.mgy.config; 2 3 import java.util.LinkedHashMap; 4 import java.util.Map; 5 6 import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 7 import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 8 import org.springframework.context.annotation.Bean; 9 import org.springframework.context.annotation.Configuration; 10 11 import cn.mgy.realm.ShiroRealm; 12 13 @Configuration 14 public class ShiroConfig { 15 16 //1.配置securityFilterBean对象 17 @Bean(name="securityFilter") 18 public Object getShiroFilterFactory() { 19 ShiroFilterFactoryBean factory=new ShiroFilterFactoryBean(); 20 21 //设置属性 22 factory.setLoginUrl("/login"); 23 factory.setSuccessUrl("/index"); 24 factory.setSecurityManager(this.getSecurityManager()); 25 //基于配置的权限过滤器,顺序执行,所以使用LinkedHashMap 26 Map<String, String> filterChainDefinition=new LinkedHashMap<>(); 27 filterChainDefinition.put("/**", "authc"); 28 factory.setFilterChainDefinitionMap(filterChainDefinition); 29 30 Object securityFilter=null; 31 try { 32 securityFilter = factory.getObject(); 33 } catch (Exception e) { 34 e.printStackTrace(); 35 } 36 return securityFilter; 37 } 38 39 //2.获得securityManager对象 40 @Bean(name="securityManager") 41 public DefaultWebSecurityManager getSecurityManager() { 42 DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager(); 43 //设置需要的realm对象 44 securityManager.setRealm(this.getRealm()); 45 return securityManager; 46 } 47 48 //3.配置realm对象 49 @Bean 50 public ShiroRealm getRealm(){ 51 ShiroRealm realm=new ShiroRealm(); 52 return realm; 53 } 54 55 }