shiro是Java的一个安全框架,其中认证、授权也是其核心知识。下面以一个maven构建的运用shiro框架的Web项目示例进行
分析和讲解,来理解shiro关于身份认证、和角色认证及权限认证的处理过程。
一、shiro集成web项目需配置的地方
说明:在进行如下配置之前,需建立maven管理的web项目(参考创建maven管理的web项目)。这里不再赘述。
1、pom.xml文件添加shiro依赖的jar包
2、web.xml配置添加 初始化shiro环境配置
3、shiro.ini配置
二、查看演示结果及分析
分以下几种情况进行演示
1、请求登录页面,无需权限验证(不然,一直在进行死循环)
http://localhost:8080/shiroWeb/login
2、请求admin页面,需身份认证,跳转到登录页面。
http://localhost:8080/shiroWeb/admin
用户登入,进行身份验证之后,后台会记录session,下次在请求admin页面,即可直接访问admin页面。
3、请求student页面,需身份认证和角色认证。
http://localhost:8080/shiroWeb/student
用户登入后,进行身份认证,身份认证通过后,还需进行角色认证,角色认证通过,才能访问student页面。
否则,还是无权限。
角色认证通过(该用户拥有改角色):
角色认证不通过(该用户不具有该角色):
4、请求teacher页面,需身份认证和角色认证及权限认证。
http://localhost:8080/shiroWeb/teacher
用户登入后,进行身份认证,身份认证通过后,还需进行角色认证,角色认证通过,还需进行权限认证,权限认证通过,才能访问teacher页面。
否则,还是无权限。
权限认证不通过(拥有该角色的用户没有操作创建用户的权限或者,没有分配任何角色的用户):
权限认证通过(拥有该角色的用户有操作创建用户的权限):
分析:判断是否具有请求某个页面的操作,首先需进行身份认证(登录页面除外),身份认证(authc)通过后,有需要进行授权认证的,还需再验证是否需角色权限(roles)认证。
角色权限认证通过后,有需要进行资源权限认证的,还需进行资源操作权限(perms)认证 。层次递进,具体还需看如何配置,及平台如何分配。
业务理解: 用户分配某个角色,某个角色具有操作某块资源的权限。
三、附上部分代码供参考:
pom.xml文件
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.hik.shiro</groupId> 5 <artifactId>shiroWeb</artifactId> 6 <packaging>war</packaging> 7 <version>0.0.1-SNAPSHOT</version> 8 <name>shiroWeb Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <dependencies> 11 <dependency> 12 <groupId>junit</groupId> 13 <artifactId>junit</artifactId> 14 <version>4.8.1</version> 15 <scope>test</scope> 16 </dependency> 17 18 <!--添加servlet支持 --> 19 <dependency> 20 <groupId>javax.servlet</groupId> 21 <artifactId>javax.servlet-api</artifactId> 22 <version>3.1.0</version> 23 <scope>provided</scope> 24 </dependency> 25 <dependency> 26 <groupId>javax.servlet.jsp</groupId> 27 <artifactId>javax.servlet.jsp-api</artifactId> 28 <version>2.3.1</version> 29 <scope>provided</scope> 30 </dependency> 31 32 <!--添加jstl支持 --> 33 <dependency> 34 <groupId>javax.servlet</groupId> 35 <artifactId>jstl</artifactId> 36 <version>1.2</version> 37 </dependency> 38 39 <!--添加日志支持 --> 40 <dependency> 41 <groupId>log4j</groupId> 42 <artifactId>log4j</artifactId> 43 <version>1.2.17</version> 44 </dependency> 45 <dependency> 46 <groupId>commons-logging</groupId> 47 <artifactId>commons-logging</artifactId> 48 <version>1.2</version> 49 </dependency> 50 <!-- 添加shiro支持 --> 51 <dependency> 52 <groupId>org.apache.shiro</groupId> 53 <artifactId>shiro-core</artifactId> 54 <version>1.4.0</version> 55 </dependency> 56 57 <!-- 添加shrio-web支持 --> 58 <dependency> 59 <groupId>org.apache.shiro</groupId> 60 <artifactId>shiro-web</artifactId> 61 <version>1.4.0</version> 62 </dependency> 63 64 <!-- 添加slf4j支持 --> 65 <dependency> 66 <groupId>org.slf4j</groupId> 67 <artifactId>slf4j-log4j12</artifactId> 68 <version>1.7.25</version> 69 </dependency> 70 </dependencies> 71 <build> 72 <finalName>shiroWeb</finalName> 73 </build> 74 </project>
web.xml文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <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" id="WebApp_ID" version="2.5"> 3 <display-name>TestWeb</display-name> 4 <welcome-file-list> 5 <welcome-file>index.html</welcome-file> 6 <welcome-file>index.htm</welcome-file> 7 <welcome-file>index.jsp</welcome-file> 8 <welcome-file>default.html</welcome-file> 9 <welcome-file>default.htm</welcome-file> 10 <welcome-file>default.jsp</welcome-file> 11 </welcome-file-list> 12 13 <!--添加 shiro支持 --> 14 <listener> 15 <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> 16 </listener> 17 <filter> 18 <filter-name>ShiroFilter</filter-name> 19 <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> 20 </filter> 21 22 <filter-mapping> 23 <filter-name>ShiroFilter</filter-name> 24 <url-pattern>/*</url-pattern> 25 <dispatcher>REQUEST</dispatcher> 26 <dispatcher>FORWARD</dispatcher> 27 <dispatcher>INCLUDE</dispatcher> 28 <dispatcher>ERROR</dispatcher> 29 </filter-mapping> 30 31 <servlet> 32 <servlet-name>loginServlet</servlet-name> 33 <servlet-class>com.hik.servlet.LoginServlet</servlet-class> 34 </servlet> 35 <servlet-mapping> 36 <servlet-name>loginServlet</servlet-name> 37 <url-pattern>/login</url-pattern> 38 </servlet-mapping> 39 40 <servlet> 41 <servlet-name>adminServlet</servlet-name> 42 <servlet-class>com.hik.servlet.AdminServlet</servlet-class> 43 </servlet> 44 <servlet-mapping> 45 <servlet-name>adminServlet</servlet-name> 46 <url-pattern>/admin</url-pattern> 47 </servlet-mapping> 48 49 <servlet> 50 <servlet-name>studentServlet</servlet-name> 51 <servlet-class>com.hik.servlet.StudentServlet</servlet-class> 52 </servlet> 53 <servlet-mapping> 54 <servlet-name>studentServlet</servlet-name> 55 <url-pattern>/student</url-pattern> 56 </servlet-mapping> 57 58 <servlet> 59 <servlet-name>teacherServlet</servlet-name> 60 <servlet-class>com.hik.servlet.TeacherServlet</servlet-class> 61 </servlet> 62 <servlet-mapping> 63 <servlet-name>teacherServlet</servlet-name> 64 <url-pattern>/teacher</url-pattern> 65 </servlet-mapping> 66 </web-app>
shiro.inn文件
1 [main] 2 authc.loginUrl=/login.jsp 3 roles.unauthorizedUrl=/unauthorized.jsp 4 perms.unauthorizedUrl=/unauthorized.jsp 5 [users] 6 hik=123456,admin 7 jack=123,teacher 8 marry=234 9 json=345 10 [roles] 11 admin=user:* 12 teacher=student:* 13 [urls] 14 /login=anon 15 /admin=authc 16 /student=authc,roles[teacher] 17 /teacher=perms["user:create"]
loginServlet.java
1 /** 2 * 3 */ 4 package com.hik.servlet; 5 6 import java.io.IOException; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import org.apache.shiro.SecurityUtils; 14 import org.apache.shiro.authc.UsernamePasswordToken; 15 import org.apache.shiro.subject.Subject; 16 import org.slf4j.Logger; 17 import org.slf4j.LoggerFactory; 18 19 /** 20 * @ClassName: LoginServlet 21 * @Description: TODO 22 * @author jed 23 * @date 2017年7月16日下午12:29:16 24 * 25 */ 26 public class LoginServlet extends HttpServlet{ 27 28 private static final Logger log = LoggerFactory.getLogger(LoginServlet.class); 29 30 /** 31 * 序列号 32 */ 33 private static final long serialVersionUID = 1L; 34 35 @Override 36 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 37 System.out.println("login doget"); 38 log.info("login doget"); 39 req.getRequestDispatcher("login.jsp").forward(req, resp); 40 } 41 42 @Override 43 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 44 System.out.println("login dopost"); 45 log.info("login dopost"); 46 String userName = req.getParameter("userName"); 47 String password = req.getParameter("password"); 48 UsernamePasswordToken token = new UsernamePasswordToken(userName,password); 49 Subject subject = SecurityUtils.getSubject(); 50 try{ 51 subject.login(token); 52 resp.sendRedirect("success.jsp"); //重定向 53 }catch(Exception e){ 54 log.error("登录失败", e); 55 req.setAttribute("errorInfo", "用户名或者密码错误"); 56 req.getRequestDispatcher("login.jsp").forward(req, resp);//请求转发 57 } 58 } 59 60 61 62 }
studentServlet.java
1 /** 2 * 3 */ 4 package com.hik.servlet; 5 6 import java.io.IOException; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import org.apache.shiro.SecurityUtils; 14 import org.apache.shiro.authc.UsernamePasswordToken; 15 import org.apache.shiro.subject.Subject; 16 import org.slf4j.Logger; 17 import org.slf4j.LoggerFactory; 18 19 /** 20 * @ClassName: LoginServlet 21 * @Description: TODO 22 * @author jed 23 * @date 2017年7月16日下午12:29:16 24 * 25 */ 26 public class StudentServlet extends HttpServlet{ 27 28 private static final Logger log = LoggerFactory.getLogger(StudentServlet.class); 29 30 /** 31 * 序列号 32 */ 33 private static final long serialVersionUID = 1L; 34 35 @Override 36 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 37 System.out.println("student doget"); 38 log.info("student doget"); 39 req.getRequestDispatcher("student.jsp").forward(req, resp); 40 } 41 42 @Override 43 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 44 System.out.println("student dopost"); 45 log.info("student dopost"); 46 } 47 48 49 50 }