1、Web集成原理分析
【1】web集成的配置
还记得吗,以前我们在没有与WEB环境进行集成的时候,为了生成SecurityManager对象,是通过手动读取配置文件生成工厂对象,再通过工厂对象获取到SecurityManager的。就像下面代码展示的那样
1. /** 2. * @Description 登录方法 3. */ 4. private Subject shiroLogin(String loginName,String password) { 5. //导入权限ini文件构建权限工厂 6. Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); 7. //工厂构建安全管理器 8. SecurityManager securityManager = factory.getInstance(); 9. //使用SecurityUtils工具生效安全管理器 10. SecurityUtils.setSecurityManager(securityManager); 11. //使用SecurityUtils工具获得主体 12. Subject subject = SecurityUtils.getSubject(); 13. //构建账号token 14. UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginName, password); 15. //登录操作 16. subject.login(usernamePasswordToken); 17. return subject; 18. }
不过,现在我们既然说要与WEB集成,那么首先要做的事情就是把我们的shiro.ini这个配置文件交付到WEB环境中,定义shiro.ini文件如下
1. #声明自定义的realm,且为安全管理器指定realms 2. [main] 3. definitionRealm=com.itheima.shiro.realm.DefinitionRealm 4. securityManager.realms=$definitionRealm
【1.1】新建项目
新建web项目shiro-day01-07web,其中realm、service、resources内容从shiro-day01-06authentication-realm中拷贝即可
【1.2】pom.xml配置
1. <?xml version="1.0" encoding="UTF-8"?> 2. 3. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5. <modelVersion>4.0.0</modelVersion> 6. 7. <groupId>com.itheima.shiro</groupId> 8. <artifactId>shiro-day01-07web</artifactId> 9. <version>1.0-SNAPSHOT</version> 10. <packaging>war</packaging> 11. 12. <name>shiro-day01-07web Maven Webapp</name> 13. <!-- FIXME change it to the project's website --> 14. <url>http://www.example.com</url> 15. 16. <dependencies> 17. 18. <dependency> 19. <groupId>commons-logging</groupId> 20. <artifactId>commons-logging</artifactId> 21. <version>1.1.3</version> 22. </dependency> 23. 24. <dependency> 25. <groupId>org.apache.shiro</groupId> 26. <artifactId>shiro-core</artifactId> 27. <version>1.3.2</version> 28. </dependency> 29. 30. <dependency> 31. <groupId>org.apache.shiro</groupId> 32. <artifactId>shiro-web</artifactId> 33. <version>1.3.2</version> 34. </dependency> 35. 36. <dependency> 37. <groupId>junit</groupId> 38. <artifactId>junit</artifactId> 39. <version>4.11</version> 40. </dependency> 41. 42. </dependencies> 43. 44. <build> 45. <plugins> 46. <!-- tomcat7插件,命令: mvn tomcat7:run -DskipTests --> 47. <plugin> 48. <groupId>org.apache.tomcat.maven</groupId> 49. <artifactId>tomcat7-maven-plugin</artifactId> 50. <version>2.2</version> 51. <configuration> 52. <uriEncoding>utf-8</uriEncoding> 53. <port>8080</port> 54. <path>/platform</path> 55. </configuration> 56. </plugin> 57. 58. <!-- compiler插件, 设定JDK版本 --> 59. <plugin> 60. <groupId>org.apache.maven.plugins</groupId> 61. <artifactId>maven-compiler-plugin</artifactId> 62. <version>3.1</version> 63. <configuration> 64. <source>8</source> 65. <target>8</target> 66. <showWarnings>true</showWarnings> 67. </configuration> 68. </plugin> 69. </plugins> 70. </build> 71. </project>
【1.3】web.xml配置
1. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2. xmlns="http://java.sun.com/xml/ns/javaee" 3. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 4. version="3.0"> 5. <display-name>shiro-day01-07web</display-name> 6. 7. <!-- 初始化SecurityManager对象所需要的环境--> 8. <context-param> 9. <param-name>shiroEnvironmentClass</param-name> 10. <param-value>org.apache.shiro.web.env.IniWebEnvironment</param-value> 11. </context-param> 12. 13. <!-- 指定Shiro的配置文件的位置 --> 14. <context-param> 15. <param-name>shiroConfigLocations</param-name> 16. <param-value>classpath:shiro.ini</param-value> 17. </context-param> 18. 19. <!-- 监听服务器启动时,创建shiro的web环境。 20. 即加载shiroEnvironmentClass变量指定的IniWebEnvironment类--> 21. <listener> 22. <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> 23. </listener> 24. 25. <!-- shiro的l过滤入口,过滤一切请求 --> 26. <filter> 27. <filter-name>shiroFilter</filter-name> 28. <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> 29. </filter> 30. <filter-mapping> 31. <filter-name>shiroFilter</filter-name> 32. <!-- 过滤所有请求 --> 33. <url-pattern>/*</url-pattern> 34. </filter-mapping> 35. 36. </web-app>
【2】SecurityManager对象创建
上面我们集成shiro到web项目了,下面我们来追踪下源码,看下SecurityManager对象是如何创建的
(1)我启动了服务器,监听器捕获到了服务器启动事件。我现在所处的位置EnvironmentLoaderListener监听器的入口处
(2)进入方法内查看,它先根据我们的shiroEnvironmentClass变量的值org.apache.shiro.web.env.IniWebEnvironment,初始化一个shiro环境对象
(3)最后在创建一个SecurityManager对象,再将其绑定到刚才通过字节码创建的Shiro环境对象中
到这来SecurityManager就完成了初始化
2、Shiro默认过滤器
Shiro内置了很多默认的过滤器,比如身份验证、授权等相关的。默认过滤器可以参考org.apache.shiro.web.filter.mgt.DefaultFilter中的枚举过滤器
【1】认证相关
过滤器 | 过滤器类 | 说明 | 默认 |
authc | FormAuthenticationFilter | 基于表单的过滤器;如“/**=authc”,如果没有登录会跳到相应的登录页面登录 | 无 |
logout | LogoutFilter | 退出过滤器,主要属性:redirectUrl:退出成功后重定向的地址,如“/logout=logout” | / |
anon | AnonymousFilter | 匿名过滤器,即不需要登录即可访问;一般用于静态资源过滤;示例“/static/**=anon” | 无 |
【2】授权相关
过滤器 | 过滤器类 | 说明 | 默认 |
roles | RolesAuthorizationFilter | 角色授权拦截器,验证用户是否拥有所有角色;主要属性: loginUrl:登录页面地址(/login.jsp);unauthorizedUrl:未授权后重定向的地址;示例“/admin/**=roles[admin]” | 无 |
perms | PermissionsAuthorizationFilter | 权限授权拦截器,验证用户是否拥有所有权限;属性和roles一样;示例“/user/**=perms["user:create"]” | 无 |
port | PortFilter | 端口拦截器,主要属性:port(80):可以通过的端口;示例“/test= port[80]”,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样 | 无 |
rest | HttpMethodPermissionFilter | rest风格拦截器,自动根据请求方法构建权限字符串(GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)构建权限字符串;示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll) | 无 |
ssl | SslFilter | SSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口(443);其他和port拦截器一样; | 无 |
3、Web集成完整案例
基于shiro-day01-07web继续集成
【1】编写pom.xml
1. <?xml version="1.0" encoding="UTF-8"?> 2. 3. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5. <modelVersion>4.0.0</modelVersion> 6. 7. <groupId>com.itheima.shiro</groupId> 8. <artifactId>shiro-day01-07web</artifactId> 9. <version>1.0-SNAPSHOT</version> 10. <packaging>war</packaging> 11. 12. <name>shiro-day01-07web Maven Webapp</name> 13. <!-- FIXME change it to the project's website --> 14. <url>http://www.example.com</url> 15. 16. <dependencies> 17. 18. <dependency> 19. <groupId>commons-logging</groupId> 20. <artifactId>commons-logging</artifactId> 21. <version>1.1.3</version> 22. </dependency> 23. 24. <dependency> 25. <groupId>org.apache.shiro</groupId> 26. <artifactId>shiro-core</artifactId> 27. <version>1.3.2</version> 28. </dependency> 29. 30. <dependency> 31. <groupId>org.apache.shiro</groupId> 32. <artifactId>shiro-web</artifactId> 33. <version>1.3.2</version> 34. </dependency> 35. 36. <dependency> 37. <groupId>junit</groupId> 38. <artifactId>junit</artifactId> 39. <version>4.11</version> 40. </dependency> 41. 42. <dependency> 43. <groupId>javax.servlet</groupId> 44. <artifactId>javax.servlet-api</artifactId> 45. <version>3.0.1</version> 46. <scope>provided</scope> 47. </dependency> 48. <dependency> 49. <groupId>jstl</groupId> 50. <artifactId>jstl</artifactId> 51. <version>1.2</version> 52. </dependency> 53. <dependency> 54. <groupId>taglibs</groupId> 55. <artifactId>standard</artifactId> 56. <version>1.1.2</version> 57. </dependency> 58. 59. </dependencies> 60. 61. <build> 62. <plugins> 63. <!-- tomcat7插件,命令: mvn tomcat7:run -DskipTests --> 64. <plugin> 65. <groupId>org.apache.tomcat.maven</groupId> 66. <artifactId>tomcat7-maven-plugin</artifactId> 67. <version>2.2</version> 68. <configuration> 69. <uriEncoding>utf-8</uriEncoding> 70. <port>8080</port> 71. <path>/platform</path> 72. </configuration> 73. </plugin> 74. 75. <!-- compiler插件, 设定JDK版本 --> 76. <plugin> 77. <groupId>org.apache.maven.plugins</groupId> 78. <artifactId>maven-compiler-plugin</artifactId> 79. <version>3.1</version> 80. <configuration> 81. <source>8</source> 82. <target>8</target> 83. <showWarnings>true</showWarnings> 84. </configuration> 85. </plugin> 86. </plugins> 87. </build> 88. </project>
【2】编写shiro.ini文件
1. #声明自定义的realm,且为安全管理器指定realms 2. [main] 3. definitionRealm=com.itheima.shiro.realm.DefinitionRealm 4. securityManager.realms=$definitionRealm 5. #用户退出后跳转指定JSP页面 6. logout.redirectUrl=/login.jsp 7. #若没有登录,则被authc过滤器重定向到login.jsp页面 8. authc.loginUrl = /login.jsp 9. [urls] 10. /login=anon 11. #发送/home请求需要先登录 12. /home= authc 13. #发送/order/list请求需要先登录 14. /order-list = roles[admin] 15. #提交代码需要order:add权限 16. /order-add = perms["order:add"] 17. #更新代码需要order:del权限 18. /order-del = perms["order:del"] 19. #发送退出请求则用退出过滤器 20. /logout = logout