面试专题系列-Shiro

article/2025/10/7 16:08:10

1.什么是shiro

在这里插入图片描述
Apache Shiro 是 Java 的一个安全框架。使用 shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE环境,也可以用在 JavaEE 环境。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。

2.Shiro基本模块

在这里插入图片描述
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

3.什么是RBAC

RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。

4.RBAC权限模型表设计

在RBAC模型里面,有3个基础组成部分,分别是:用户、角色和权限。

RBAC通过定义角色的权限,并对用户授予某个角色从而来控制用户的权限,实现了用户和权限的逻辑分离(区别于ACL模型),极大地方便了权限的管理

下面在讲解之前,先介绍一些名词:

User(用户):每个用户都有唯一的UID识别,并被授予不同的角色
Role(角色):不同角色具有不同的权限
Permission(权限):访问权限

用户-角色映射:用户和角色之间的映射关系
角色-权限映射:角色和权限之间的映射
它们之间的关系如下图所示:
在这里插入图片描述
如下图,管理员和普通用户被授予不同的权限,普通用户只能去修改和查看个人信息,而不能创建创建用户和冻结用户,而管理员由于被授予所有权限,所以可以做所有操作。
在这里插入图片描述

5.Shiro架构

外部架构(以应用程序角度)
在这里插入图片描述
内部架构
在这里插入图片描述

6.Shiro的过滤器

当运行一个Web应用程序时,Shiro将会创建一些有用的默认 Filter 实例,并自动地将它们置为可用,而这些默认的 Filter 实例是被 DefaultFilter 枚举类定义的
在这里插入图片描述
在这里插入图片描述
注意:anon, authc, authcBasic, user 是第一组认证过滤器,perms, port, rest, roles, ssl 是第二组授权过滤器,要通过授权过滤器,就先要完成登陆认证操作(即先要完成认证才能前去寻找授权) 才能走第二组授权器(例如访问需要 roles 权限的 url,如果还没有登陆的话,会直接跳转到 shiroFilterFactoryBean.setLoginUrl(); 设置的 url )

7. Shiro的核心概念Subject、SecurityManager、Realm

Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如爬虫、机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者。

SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是shiro的核心, SecurityManager相当于spring mvc中的dispatcherServlet前端控制器。

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

8. Shiro认证过程

扼要流程:

1、首先调用Subject.login(token)进行登录,他会委托给SecurityManager
2、SecurityManager负责真正的身份验证逻辑;它会委托给Authenticator进行身份验证;
3、Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,如果没有就返回认证失败,有的话就继续执行操作。

详细源码流程

②. Subject 实例委托应用程序的 SecurityManager 通过调用securityManager.login(token) 开始真正的验证。
Subject 实例(通常为 DelegatingSubject或它的子类)

③. SubjectManager 接收 token,调用内部的 Authenticator 实例调用 authenticator.authenticate(token).Authenticator 通常是一个 ModularRealmAuthenticator 实例, 支持在身份验证中协调一个或多个Realm 实例

④. 如果应用程序中配置了一个以上的 Realm, ModularRealmAuthenticator 实例将利用配置好的AuthenticationStrategy 来启动 Multi-Realm 认证尝试。在Realms 被身份验证调用之前、调用期间、调用之后,AuthenticationStrategy 被调用使其能够对每个Realm 的结果作出反应。(AuthenticationStrategy都会被调用,对每个Realm 的结果作出反应)

⑤. 每个配置的 Realm 用来帮助看它是否支持提交的 AuthenticationToken. 如果支持, 那么支持 Realm 的 getAuthenticationInfo 方法将会伴随着提交的 token 被调用. getAuthenticationInfo 方法有效地代表一个特定 Realm 的单一的身份验证尝试。

9.Shiro授权过程

①. 应用程序或框架代码调用任何 Subject 的hasRole*, checkRole*, isPermitted*,或者checkPermission*方法的变体, 传递任何所需的权限

②. Subject 的实例 调用securityManager 的对应的方法.
Subject 实例(通常为 DelegatingSubject或它的子类)

③. SecurityManager 调用 org.apache.shiro.authz.Authorizer 接口的对应方法.默认情况下,authorizer 实例是一个 ModularRealmAuthorizer 实例, 它支持协调任何授权操作过程中的一个或多个Realm 实例

④. 每个配置好的 Realm 被检查是否实现了相同的 Authorizer 接口. 如果是, Realm 各自的 hasRole*, checkRole*,isPermitted*,或 checkPermission* 方法将被调用。

10.Authorization 授权方式

授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等)。在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)

前提就是在Realm的授权方法中查询出权限

在这里插入图片描述

配置方式:
在这里插入图片描述
注解方式:
开启controller类aop支持

 //--------------开启Shiro注解授权---------------@Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);return defaultAdvisorAutoProxyCreator;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {AuthorizationAttributeSourceAdvisor sourceAdvisor = new AuthorizationAttributeSourceAdvisor();sourceAdvisor.setSecurityManager(defaultWebSecurityManager);return sourceAdvisor;}

在controller方法中添加注解
在这里插入图片描述
页面标签方法:(页面上根据权限设置菜单显示与否)
在这里插入图片描述
当调用controller的一个方法,由于该 方法加了@RequiresPermissions("item:query") ,shiro调用realm获取数据库中的权限信息,看"item:query"是否在权限数据中存在,如果不存在就拒绝访问,如果存在就授权通过。

当展示一个j页面时,页面中如果遇到<shiro:hasPermission name="item:update">,shiro调用realm获取数据库中的权限信息,看item:update是否在权限数据中存在,如果不存在就拒绝访问,如果存在就授权通过。

11.Session Manager 会话管理

Session
所谓session,即用户访问应用时保持的连接关系,在多次交互中应用能够识别出当前访问的用户是谁,且可以在多次交互中保存一些数据。

Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
session.getId(); // 获取当前session的唯一标识
session.getHost(); // 获取当前Subject的主机地址,该地址是通过HostAuthenticationToken.getHost()提供的
session.getTimeOut(); // 获取超时时间
session.setTimeOut(); // 设置超时时间(不设置默认是全局过期时间)
session.touch(); // 更新最后访问时间
session.stop(); // 销毁session,当Subject.logout()时会自动调用stop方法来销毁会话。如果在web中,调用javax.servlet.http.HttpSession.invalidate()也会自动调用shiro session.top方法进行销毁shiro的会话
session.setAttribute(“key”,”123”); // 设置session属性
session.getAttribute(“key”); // 获取session属性
session.removeAttribute(“key”); // 删除属性

注:Shiro提供的会话可以用于javaSE/javaEE环境,不依赖于任何底层容器,可以独立使用,是完整的会话模块。

Session manager 会话管理器

会话管理器管理着应用中所有Subject的会话的创建、维护、删除、失效、验证等工作。是Shiro的核心组件,顶层组件SecurityManager直接继承了SessionManager,且提供了SessionSecurityManager实现直接把会话管理委托给相应的SessionManager、DefaultSecurityManager及DefaultWebSecurityManager 默认SecurityManager都继承了SessionSecurityManager。

Shiro提供了三个默认实现:

DefaultSessionManager:DefaultSecurityManager使用的默认实现,用于JavaSE环境;
ServletContainerSessionManager: DefaultWebSecurityManager使用的默认实现,用于Web环境,其直接使用Servlet容器的会话;
DefaultWebSessionManager:用于Web环境的实现,可以替代ServletContainerSessionManager,自己维护着会话,直接废弃了Servlet容器的会话管理。

12.shiro的优点

1、 简单的身份验证,支持多种数据源
2、对角色的简单授权,支持细粒度的授权(方法)
3、支持一级缓存,以提升应用程序的性能
4、内置基于POJO的企业会话管理,适用于web及非web环境
5、非常简单的API加密
6、不跟任何框架绑定,可以独立运行


http://chatgpt.dhexx.cn/article/WKPvi93a.shtml

相关文章

shiro(详解)

这里写自定义目录标题 什么是shiro什么是权限管理什么是身份认证什么是授权SubjectSecurityManagerAuthenticatorAuthorizerRealmSessionManagerSessionDAOCacheManagerCryptography面试题认证的开发1. 创建项目并引入依赖2. 引入shiro配置文件并加入如下配置 自定义Realm自定义…

【JAVA面试题整理】框架之Shiro

一、简单介绍一下Shiro框架 Apache Shiro是java的一个安全框架。使用shiro可以非常容易的开发出足够好的应用&#xff0c;其不仅可以用在JavaSE环境&#xff0c;也可以用在JavaEE环境。Shiro可以帮助我们完成&#xff1a;认证、授权、加密、会话管理、与Web集成、缓存等。 三…

shiro总结

shiro主要内容: 1:SecurityUtils shiro提供的工具类,主要作用是获取 SecurityManager和Subject public abstract class SecurityUtils {private static SecurityManager securityManager;//获取Subjectpublic static Subject getSubject() {Subject subject ThreadContext.…

Java面试系列总结 :Shiro

1. 简单介绍一下Shiro框架 Apache Shiro是Java的一个安全框架。使用shiro可以非常容易的开发出足够好的应用&#xff0c;其不仅可以用在JavaSE环境&#xff0c;也可以用在JavaEE环境。Shiro可以帮助我们完成&#xff1a;认证、授权、加密、会话管理、与Web集成、缓存等。 三个…

Shiro知识总结二

3. 与 Spring Boot 整合 3.1 框架整合 依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>o…

Shiro相关知识

1、Shiro功能概述 Apache Shiro是一个功能强大且易于使用的 Java 安全框架&#xff0c;可执行身份验证、授权、加密和会话管理。 主要功能&#xff1a; Authentication&#xff1a;身份认证。登录时验证身份信息。 Authorization&#xff1a;授权操作。访问控制的过程&…

Spring、SpringMVC、Shiro面试题

Tags : JavaEE,Spring,面试题发表时间&#xff1a; 2014-11-29 15:03:53 原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 比如&#xff1a; 转自&#xff1a;Su的技术博客 原文地址&#xff…

Shiro知识总结一

1. 基础知识 1.1 什么是Shiro Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。Shiro 可以完成&#xff1a;认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应…

Shiro总结面试问题

Shiro总结 Shiro可做哪些事&#xff1a; 认证、授权、加密、会话管理、与web集成、缓存等 最简单的Shiro应用是怎样运行的&#xff1a; 应用代码通过Subject来进行认证和授权&#xff0c;而Subject又委托给SecurityManager 我们需要给Shiro的SecurityManager注入Realm,从而让S…

python中socket进行多线程,利用 Socket怎么在Python项目中实现一个多线程并发功能...

利用 Socket怎么在Python项目中实现一个多线程并发功能 发布时间:2020-12-11 13:55:06 来源:亿速云 阅读:95 作者:Leah 这篇文章给大家介绍利用 Socket怎么在Python项目中实现一个多线程并发功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 1.S…

Jmeter多线程并发和压测结果分析

一、多线程并发 1. 线程组简介: (1). 线程数: 配置虚拟用户数量 (2). Ramp-Up时间:设置的虚拟用户数需要多长时间全部启动,如果线程数为10,准备时长为2,那么需要2秒钟启动10个线程,也就是每秒钟启动5个线程。 (3). 循环次数 (4). 调度器-持续时间(秒),压测多长时间…

面试必问!多线程并发问题

多线程并发问题&#xff0c;基本是面试必问的。 大部分同学应该都知道Synchronized&#xff0c;Lock&#xff0c;部分同学能说到volatile、并发包&#xff0c;优秀的同学则能在前面的基础上&#xff0c;说出Synchronized、volatile的原理&#xff0c;以及并发包中常用的数据结…

实际场景中的多线程并发编程案例

目录 使用多线程的意义&#xff1a; CountDownLatch 案例一&#xff1a;多线程同步发起并发请求 案例二&#xff1a;rocketmq内&#xff0c;每个broker将自己注册到所有的nameserver时 案例三&#xff1a;利用异步线程实现同步请求 CompletableFuture 应用一&#xff1a…

【已解决】利用 Java 多线程并发编程提高数据处理效率

&#x1f389;工作场景中遇到这样一个需求&#xff1a;根据主机的 IP 地址联动更新其他模型的相关信息。需求很简单&#xff0c;只涉及一般的数据库联动查询以及更新操作&#xff0c;然而在编码实现过程中发现&#xff0c;由于主机的数量很多&#xff0c;导致循环遍历查询、更新…

c++ 多线程并发

基于C11的线程池(threadpool),简洁且可以带任意多的参数 - _Ong - 博客园 C11多线程编程(六)——线程池的实现 1. ① thread #include <iostream> #include <thread>class A { public:void operator()() {std::cout << "11111\n";} };int main…

python多线程并发请求

再api测试时&#xff0c;避免不了高并发的测试情况。所以以下案例为线程并发请求代码&#xff0c;以请求百度为例 #!/usr/bin/env python #!coding:utf-8 from __future__ import division from threading import Thread import requests import matplotlib.pyplot as plt imp…

多线程并发的一些解决思路

一、利用不变性解决并发问题 不变性&#xff08;Immutability&#xff09;模式。所谓不变性&#xff0c;简单来讲&#xff0c;就是对象一旦被创建之后&#xff0c;状态就不再发生变化。换句话说&#xff0c;就是变量一旦被赋值&#xff0c;就不允许修改了&#xff08;没有写操…

python之多线程并发

前言 今天呢笔者想和大家来聊聊python多线程的并发&#xff0c;废话就不多说了咱们直接进入主题哟。 一、线程执行 python的内置模块提供了两个内置模块&#xff1a;thread和threading&#xff0c;thread是源生模块&#xff0c;threading是扩展模块&#xff0c;在thread的基础…

python多线程并发测试

python多线程 文章目录 python多线程一、并发与并行&#xff1f;二、同步与异步的概念&#xff1f;三、线程与进程的区别&#xff1f;需求1&#xff1a;多线程执行不同任务&#xff1a;需求2&#xff1a;多线程执行相同任务&#xff1a;1.threading并发性2.多线程并发---资源共…

JAVA多线程并发

JAVA并发知识库 JAVA线程实现/创建方式 1.继承Thread类 Thread类本质上时实现了Runnable接口的一个实例&#xff0c;代表一个现成的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法&#xff0c;它将启动一个新线程&#xff0c;并执…