• Shiro入门基础知识&&案例实现&&与Web的集成


    目录

    一、Shiro简介

            1.1 什么是Shiro?

            1.2 Shiro的三个核心类

            1.3 Shiro架构图

    二、Shiro入门案例

            2.1 导入pom依赖

            2.2 配置框架配置文件

            2.3 使用Shiro

    三、Shiro与Web容器集成

            3.1 集成的测试步骤

                    3.1.1 准备一个shiro-web.ini文件

                    3.1.2 通过web.xml将shiro与web容器进行集成

                    3.1.3 编写servlet

                    3.1.4 测试

            3.2 测试使用的前端页面


    ​​​​​​​一、Shiro简介

            1.1 什么是Shiro?

            shiro是apache的一个开源框架,是一个权限管理的框架,可以实现 用户认证、用户授权。

            shiro不依赖于spring,不仅可以实现 web应用的权限管理,还可以实现c/s系统、分布式系统权限管理,shiro属于轻量框架,越来越多企业项目开始使用shiro。

            1.2 Shiro的三个核心类

    Subject主体,代表了当前“用户”,它只是一个抽象概念;

                    与Subject的所有交互都会委托给SecurityManager;

                    可以把Subject认为是一个门面;SecurityManager才是实际的执行者;

    SecurityManager安全管理器;它管理着所有Subject;可以看出它是Shiro 的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器;

    Realm,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源

      

            1.3 Shiro架构图

    1、subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。

    2、securityManager:安全管理器,主体进行认证和授权都是通过securityManager进行。securityManager是一个集合,真正做事的不是securityManager而是它里面的东西。

    3、authenticator:认证器,主体进行认证最终通过authenticator进行的。

    4、authorizer:授权器,主体进行授权最终通过authorizer进行的。

    5、sessionManager:web应用中一般是用web容器(中间件tomcat)对session进行管理,shiro也提供一套session管理的方式。

          shiro不仅仅可以用于web管理也可以用于cs管理,所以他不用web容器的session管理。

    6、SessionDao:  通过SessionDao管理session数据,针对个性化的session数据存储需要使用sessionDao(如果用tomcat管理session就不用SessionDao,如果要分布式的统一管理session就要用到SessionDao)。

    7、cache Manager:缓存管理器,主要对session和授权数据进行缓存(权限管理框架主要就是对认证和授权进行管理,session是在服务器缓存中的),比如将授权数据通过cacheManager进行缓存管理和ehcache整合对缓存数据进行管理(redis是缓存框架)。

    8、realm:域,领域,相当于数据源,通过realm存取认证、授权相关数据(原来是通过数据库取的)。

         注意:authenticator认证器和authorizer授权器调用realm中存储授权和认证的数据和逻辑。

    9、cryptography:密码管理,比如md5加密,提供了一套加密/解密的组件,方便开发。比如提供常用的散列、加/解密等功能。比如 md5散列算法(md5只有加密没有解密)。

    对Shiro框架的简介做个总结,它的主要作用:

            ① 认证 ---> 接管了用户登录操作;

            ② 授权 ---> 接管了系统资源的分配;

            ③ 会话管理 ---> 接管了tomcat中的session;

            ④ 缓存管理 ---> 主要提升了权限管理的执行效率;

            ⑤ 密码管理 ---> 对密码进行加密;


    二、Shiro入门案例

    由于shiro与日志有所关系,所以我们还是先导入日志配置文件;

    log4j2.xml

    1. "1.0" encoding="UTF-8"?>
    2. <Configuration status="WARN" monitorInterval="30">
    3. <Properties>
    4. <Property name="LOG_HOME">/root/workspace/lucenedemo/logsProperty>
    5. <property name="ERROR_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/errorproperty>
    6. <property name="WARN_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/warnproperty>
    7. <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%nproperty>
    8. Properties>
    9. <Appenders>
    10. <Console name="Console" target="SYSTEM_OUT">
    11. <ThresholdFilter level="trace" onMatch="ACCEPT"
    12. onMismatch="DENY" />
    13. <PatternLayout pattern="${PATTERN}" />
    14. Console>
    15. <File name="log" fileName="logs/test.log" append="false">
    16. <PatternLayout
    17. pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    18. File>
    19. <RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log"
    20. filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
    21. <ThresholdFilter level="info" onMatch="ACCEPT"
    22. onMismatch="DENY" />
    23. <PatternLayout
    24. pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    25. <Policies>
    26. <TimeBasedTriggeringPolicy interval="1"
    27. modulate="true" />
    28. Policies>
    29. RollingFile>
    30. <RollingFile name="RollingFileWarn" fileName="${WARN_LOG_FILE_NAME}/warn.log"
    31. filePattern="${WARN_LOG_FILE_NAME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
    32. <ThresholdFilter level="warn" onMatch="ACCEPT"
    33. onMismatch="DENY" />
    34. <PatternLayout
    35. pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    36. <Policies>
    37. <TimeBasedTriggeringPolicy />
    38. <SizeBasedTriggeringPolicy size="2 kB" />
    39. Policies>
    40. <DefaultRolloverStrategy max="20" />
    41. RollingFile>
    42. <RollingFile name="RollingFileError" fileName="${ERROR_LOG_FILE_NAME}/error.log"
    43. filePattern="${ERROR_LOG_FILE_NAME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd-HH-mm}-%i.log">
    44. <ThresholdFilter level="error" onMatch="ACCEPT"
    45. onMismatch="DENY" />
    46. <PatternLayout
    47. pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    48. <Policies>
    49. <TimeBasedTriggeringPolicy interval="1"
    50. modulate="true" />
    51. Policies>
    52. RollingFile>
    53. Appenders>
    54. <Loggers>
    55. <logger name="org.springframework" level="INFO">logger>
    56. <logger name="org.mybatis" level="INFO">logger>
    57. <logger name="org.springframework" level="ERROR" />
    58. <logger name="org.hibernate" level="ERROR" />
    59. <logger name="org.apache.struts2" level="ERROR" />
    60. <logger name="com.opensymphony.xwork2" level="ERROR" />
    61. <logger name="org.jboss" level="ERROR" />
    62. <root level="all">
    63. <appender-ref ref="Console" />
    64. <appender-ref ref="RollingFileInfo" />
    65. <appender-ref ref="RollingFileWarn" />
    66. <appender-ref ref="RollingFileError" />
    67. root>
    68. Loggers>
    69. Configuration>

            2.1 导入pom依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0modelVersion>
    5. <groupId>org.examplegroupId>
    6. <artifactId>shiroartifactId>
    7. <version>1.0-SNAPSHOTversion>
    8. <packaging>warpackaging>
    9. <name>shiro Maven Webappname>
    10. <url>http://www.example.comurl>
    11. <properties>
    12. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    13. <maven.compiler.source>1.7maven.compiler.source>
    14. <maven.compiler.target>1.7maven.compiler.target>
    15. <maven.compiler.plugin.version>3.7.0maven.compiler.plugin.version>
    16. <junit.version>4.12junit.version>
    17. <servlet.version>4.0.0servlet.version>
    18. <log4j2.version>2.9.1log4j2.version>
    19. <slf4j.version>1.7.7slf4j.version>
    20. <log4j2.disruptor.version>3.2.0log4j2.disruptor.version>
    21. <shiro.version>1.2.5shiro.version>
    22. properties>
    23. <dependencies>
    24. <dependency>
    25. <groupId>org.apache.shirogroupId>
    26. <artifactId>shiro-coreartifactId>
    27. <version>${shiro.version}version>
    28. dependency>
    29. <dependency>
    30. <groupId>org.apache.shirogroupId>
    31. <artifactId>shiro-webartifactId>
    32. <version>${shiro.version}version>
    33. dependency>
    34. <dependency>
    35. <groupId>junitgroupId>
    36. <artifactId>junitartifactId>
    37. <version>${junit.version}version>
    38. <scope>testscope>
    39. dependency>
    40. <dependency>
    41. <groupId>javax.servletgroupId>
    42. <artifactId>javax.servlet-apiartifactId>
    43. <version>${servlet.version}version>
    44. <scope>providedscope>
    45. dependency>
    46. <dependency>
    47. <groupId>org.slf4jgroupId>
    48. <artifactId>slf4j-apiartifactId>
    49. <version>${slf4j.version}version>
    50. dependency>
    51. <dependency>
    52. <groupId>org.slf4jgroupId>
    53. <artifactId>jcl-over-slf4jartifactId>
    54. <version>${slf4j.version}version>
    55. <scope>runtimescope>
    56. <exclusions>
    57. <exclusion>
    58. <artifactId>slf4j-apiartifactId>
    59. <groupId>org.slf4jgroupId>
    60. exclusion>
    61. exclusions>
    62. dependency>
    63. <dependency>
    64. <groupId>org.apache.logging.log4jgroupId>
    65. <artifactId>log4j-slf4j-implartifactId>
    66. <version>${log4j2.version}version>
    67. <exclusions>
    68. <exclusion>
    69. <artifactId>slf4j-apiartifactId>
    70. <groupId>org.slf4jgroupId>
    71. exclusion>
    72. exclusions>
    73. dependency>
    74. <dependency>
    75. <groupId>org.apache.logging.log4jgroupId>
    76. <artifactId>log4j-apiartifactId>
    77. <version>${log4j2.version}version>
    78. dependency>
    79. <dependency>
    80. <groupId>org.apache.logging.log4jgroupId>
    81. <artifactId>log4j-coreartifactId>
    82. <version>${log4j2.version}version>
    83. dependency>
    84. <dependency>
    85. <groupId>org.apache.logging.log4jgroupId>
    86. <artifactId>log4j-webartifactId>
    87. <version>${log4j2.version}version>
    88. <scope>runtimescope>
    89. dependency>
    90. <dependency>
    91. <groupId>com.lmaxgroupId>
    92. <artifactId>disruptorartifactId>
    93. <version>${log4j2.disruptor.version}version>
    94. dependency>
    95. dependencies>
    96. <build>
    97. <finalName>shirofinalName>
    98. <resources>
    99. <resource>
    100. <directory>src/main/javadirectory>
    101. <includes>
    102. <include>**/*.xmlinclude>
    103. includes>
    104. resource>
    105. <resource>
    106. <directory>src/main/resourcesdirectory>
    107. <includes>
    108. <include>*.propertiesinclude>
    109. <include>*.xmlinclude>
    110. <include>*.iniinclude>
    111. includes>
    112. resource>
    113. resources>
    114. <pluginManagement>
    115. <plugins>
    116. <plugin>
    117. <groupId>org.apache.maven.pluginsgroupId>
    118. <artifactId>maven-compiler-pluginartifactId>
    119. <version>${maven.compiler.plugin.version}version>
    120. <configuration>
    121. <source>${maven.compiler.source}source>
    122. <target>${maven.compiler.target}target>
    123. <encoding>${project.build.sourceEncoding}encoding>
    124. configuration>
    125. plugin>
    126. <plugin>
    127. <artifactId>maven-clean-pluginartifactId>
    128. <version>3.1.0version>
    129. plugin>
    130. <plugin>
    131. <artifactId>maven-resources-pluginartifactId>
    132. <version>3.0.2version>
    133. plugin>
    134. <plugin>
    135. <artifactId>maven-compiler-pluginartifactId>
    136. <version>3.8.0version>
    137. plugin>
    138. <plugin>
    139. <artifactId>maven-surefire-pluginartifactId>
    140. <version>2.22.1version>
    141. plugin>
    142. <plugin>
    143. <artifactId>maven-war-pluginartifactId>
    144. <version>3.2.2version>
    145. plugin>
    146. <plugin>
    147. <artifactId>maven-install-pluginartifactId>
    148. <version>2.5.2version>
    149. plugin>
    150. <plugin>
    151. <artifactId>maven-deploy-pluginartifactId>
    152. <version>2.8.2version>
    153. plugin>
    154. plugins>
    155. pluginManagement>
    156. build>
    157. project>

            2.2 配置框架配置文件

                    shiro.ini(就是放的用户信息)

    1. [users]
    2. zs=123
    3. ls=456
    4. ww=789

            2.3 使用Shiro

                    使用步骤:① 获取工厂对象;

                                      ② 获取实例;

                                      ③ 将实例交给SecurityUtils;

                                      ④ 获取登录主体;

                                      ⑤ 生成token令牌;(用户名密码)

                                      ⑥ 主体携带令牌进行登录;

    我们建立一个测试类来依次实现:

    Demo1

    1. package com.leaf.demo;
    2. import org.apache.shiro.SecurityUtils;
    3. import org.apache.shiro.authc.UsernamePasswordToken;
    4. import org.apache.shiro.config.IniSecurityManagerFactory;
    5. import org.apache.shiro.mgt.SecurityManager;
    6. import org.apache.shiro.subject.Subject;
    7. /**
    8. * @author Leaf
    9. * @site 2977819715
    10. * @company 玉渊工作室
    11. * @create  2022-08-25 0:32
    12. */
    13. public class Demo1 {
    14. public static void main(String[] args) {
    15. /*获取工厂对象;
    16.              获取实例;
    17.           将实例交给SecurityUtils;
    18.              获取登录主体;
    19.           生成令牌;
    20.              主体携带令牌进行登录;*/
    21. //工厂
    22. IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
    23. //获取安全管理器的实例
    24. SecurityManager instance = factory.getInstance();
    25. SecurityUtils.setSecurityManager(instance);
    26. //获取登录主体
    27. Subject subject = SecurityUtils.getSubject();
    28. //令牌
    29. UsernamePasswordToken token = new UsernamePasswordToken("zs", "999");
    30. //主体登录
    31. subject.login(token);
    32. System.out.println("登录成功");
    33. subject.logout();
    34. System.out.println("登出成功");
    35. }
    36. }

    我们故意放入错误的用户信息,然后运行测试一下: 

    然后我们再把用户信息改正确,再次测试: 

    1. //令牌
    2. UsernamePasswordToken token = new UsernamePasswordToken("zs", "123");

    登录成功:


    三、Shiro与Web容器集成

            实现步骤:1)web.xml文件中进行shiro过滤器配置

                              2)添加配置文件 shiro-web.ini

            3.1 集成的测试步骤

                    3.1.1 准备一个shiro-web.ini文件

            shiro-web.ini

    1. [main]
    2. #定义身份认证失败后的请求url映射,loginUrl是身份认证过滤器中的一个属性
    3. authc.loginUrl=/login
    4. #定义角色认证失败后的请求url映射,unauthorizedUrl是角色认证过滤器中的一个属性
    5. roles.unauthorizedUrl=/unauthorized.jsp
    6. #定义权限认证失败后请求url映射,unauthorizedUrl是角色认证过滤器中的一个属性
    7. perms.unauthorizedUrl=/unauthorized.jsp
    8. [users]
    9. zs=123,role1
    10. ls=123,role2
    11. ww=123,role3
    12. zdm=123,admin
    13. [roles]
    14. role1=user:create
    15. role2=user:create,user:update
    16. role3=user:create,user:update,user:delete,user:view,user:load
    17. admin=user:*
    18. #定义请求的地址需要做什么验证
    19. [urls]
    20. #请求login的时候不需要权限,游客身份即可(anon)
    21. /login.do=anon
    22. #请求/user/updatePwd.jsp的时候,需要身份认证(authc)
    23. /user/updatePwd.jsp=authc
    24. #请求/admin的时候,需要角色认证,必须是拥有admin角色的用户才行
    25. /admin/*.jsp=roles[admin]
    26. #请求/teacher的时候,需要权限认证,必须是拥有user:create权限的角色的用户才行
    27. /user/teacher.jsp=perms["user:update"]

                    3.1.2 通过web.xml将shiro与web容器进行集成

            web.xml

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    5. version="3.1">
    6. <display-name>Archetype Created Web Applicationdisplay-name>
    7. <context-param>
    8. <param-name>shiroConfigLocationsparam-name>
    9. <param-value>classpath:shiro-web.iniparam-value>
    10. context-param>
    11. <listener>
    12. <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListenerlistener-class>
    13. listener>
    14. <filter>
    15. <filter-name>ShiroFilterfilter-name>
    16. <filter-class>org.apache.shiro.web.servlet.ShiroFilterfilter-class>
    17. filter>
    18. <filter-mapping>
    19. <filter-name>ShiroFilterfilter-name>
    20. <url-pattern>/*url-pattern>
    21. filter-mapping>
    22. web-app>

                    3.1.3 编写servlet

                    LoginServlet

    1. package com.leaf.demo;
    2. import org.apache.shiro.SecurityUtils;
    3. import org.apache.shiro.authc.UsernamePasswordToken;
    4. import org.apache.shiro.subject.Subject;
    5. import javax.servlet.ServletException;
    6. import javax.servlet.annotation.WebServlet;
    7. import javax.servlet.http.HttpServlet;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import java.io.IOException;
    11. /**
    12. * @author Leaf
    13. * @site 2977819715
    14. * @company 玉渊工作室
    15. * @create  2022-08-25 1:59
    16. */
    17. @WebServlet("/login")
    18. public class LoginServlet extends HttpServlet {
    19. @Override
    20. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    21. doPost(req,resp);
    22. }
    23. @Override
    24. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    25. String username = req.getParameter("username");
    26. String password = req.getParameter("password");
    27. UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    28. Subject subject = SecurityUtils.getSubject();
    29. try {
    30. subject.login(token);
    31. req.getRequestDispatcher("/main.jsp").forward(req,resp);
    32. }catch (Exception e){
    33. req.setAttribute("message","用户名密码输入有误!!!");
    34. req.getRequestDispatcher("/login.jsp").forward(req,resp);
    35. }
    36. }
    37. }

                    LogoutServlet

    1. package com.leaf.demo;
    2. import org.apache.shiro.SecurityUtils;
    3. import org.apache.shiro.authc.UsernamePasswordToken;
    4. import org.apache.shiro.subject.Subject;
    5. import javax.servlet.ServletException;
    6. import javax.servlet.annotation.WebServlet;
    7. import javax.servlet.http.HttpServlet;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import java.io.IOException;
    11. /**
    12. * @author Leaf
    13. * @site 2977819715
    14. * @company 玉渊工作室
    15. * @create  2022-08-25 2:08
    16. */
    17. @WebServlet("/logout")
    18. public class LogoutServlet extends HttpServlet {
    19. @Override
    20. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    21. doPost(req,resp);
    22. }
    23. @Override
    24. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    25. Subject subject = SecurityUtils.getSubject();
    26. try {
    27. subject.logout();
    28. req.getRequestDispatcher("/login.jsp").forward(req,resp);
    29. }catch (Exception e){
    30. req.getRequestDispatcher("/login.jsp").forward(req,resp);
    31. }
    32. }
    33. }

                    3.1.4 测试

     

     

            3.2 测试使用的前端页面

    由于这个前端页面太多,不好粘在这里,就直接放在百度网盘上,需要的自行领取;

    链接:https://pan.baidu.com/s/1QGmS3QzEZmnjjvWb9jSagQ
    提取码:Leaf

    注:把jsp解压后,把jsp下级目录的所有文件直接粘贴到idea的webapp中,不要复制错目录结构!

    接着我们就可以来开始测试:    

    1. 身份认证成功与失败的结果
    2. 角色认证成功与失败的结果
    3. 权限认证成功与失败的结果​​​​​​​

  • 相关阅读:
    触觉智能 PurPle Pi OH(OpenHarmony)开发板
    猿创征文 | 云服务器部署——将项目部署到云服务器上
    【Spring】SpringBoot的扩展点之ApplicationContextInitializer
    数据结构-栈和队列(1)
    【Spring IOC容器加载过程】
    2023版 STM32实战12 IIC总线读写AT24C02
    Oracle之SQL plus的一些经验心得
    Python工程师Java之路(v)Socket极简代码
    Doris安装问题记录连续更新
    pytorch tensor的广播机制
  • 原文地址:https://blog.csdn.net/qq_63492318/article/details/126514533