【Shiro】 核心概念
【Shiro】 核心概念
Metadata
title: 【Shiro】 核心概念
date: 2023-01-19 13:31
tags:
- 行动阶段/完成
- 主题场景/组件
- 笔记空间/KnowladgeSpace/ProgramSpace/ModuleSpace
- 细化主题/Module/Shiro/基础
categories:
- Shiro
keywords:
- Shiro
description: 【Shiro】 核心概念
核心概念:Subject、SecurityManager 和 Realms
现在我们已经介绍了 Shiro 的优点,让我们直接进入它的 API,以便您感受一下。Shiro 的体系结构具有三个主要概念——Subject、SecurityManager 和 Realms。
Subject
当您保护您的应用程序时,可能要问自己的最相关的问题是,“谁是当前用户?” 或“当前用户是否被允许做 X”?在编写代码或设计用户界面时,我们经常会问自己这些问题:应用程序通常是基于用户故事构建的,您希望基于每个用户来表示(和保护)功能。因此,我们考虑应用程序安全性的最自然方式是基于当前用户。Shiro 的 API 在其 Subject 概念中从根本上代表了这种思维方式。
Subject一词是一个安全术语,基本上表示“当前正在执行的用户”。它只是不被称为“用户”,因为“用户”一词通常与人相关。在安全领域,术语“Subject”可以表示一个人,也可以表示第 3方进程、守护程序帐户或任何类似的东西。它只是表示“当前正在与软件交互的东西”。不过,对于大多数意图和目的,您可以将其视为 Shiro 的“用户”概念。您可以轻松地在代码中的任何位置获取 Shiro Subject,如下面的清单 1 所示。
清单1: 获取主题
import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;
...
Subject currentUser = SecurityUtils.getSubject();
==一旦你获得了 Subject,你就可以立即访问你想为当前用户使用 Shiro 做的所有事情的 90%,例如登录、注销、访问他们的会话、执行授权检查等等 - 但稍后会详细介绍. ==这里的关键点是 Shiro 的 API 在很大程度上是直观的,因为它反映了开发人员考虑“每用户”安全控制的自然倾向。在代码中的任何地方访问 Subject 也很容易,允许在需要的任何地方进行安全操作。
SecurityManager
Subject 的“幕后”对应物是 SecurityManager。Subject 表示当前用户的安全操作,而 SecurityManager 管理所有用户的安全操作。它是 Shiro 架构的核心,充当一种“伞形”对象,引用许多形成对象图的内部嵌套安全组件。但是,一旦配置了 SecurityManager 及其内部对象图,它通常就会被搁置,应用程序开发人员几乎将所有时间都花在 Subject API 上。
那么如何设置 SecurityManager 呢?好吧,这取决于您的应用程序环境。例如,Web 应用程序通常会在 web.xml 中指定一个 Shiro Servlet Filter,这将设置 SecurityManager 实例。如果您运行的是独立应用程序,则需要以其他方式配置它。但是有很多配置选项。
每个应用程序几乎总是有一个 SecurityManager 实例。它本质上是一个应用程序单例(尽管它不需要是静态单例)。就像 Shiro 中的几乎所有东西一样,默认的 SecurityManager 实现是POJO并且可以使用任何 POJO 兼容的配置机制进行配置——普通的 Java 代码、Spring XML、YAML、.properties 和 .ini 文件等。基本上任何能够实例化的东西可以使用类和调用 JavaBeans 兼容的方法。
为此,Shiro 通过基于文本的INI配置提供了默认的“公分母”解决方案。INI 易于阅读、使用简单,并且需要很少的依赖项。您还将看到,通过对对象图导航的简单理解,INI 可以有效地用于配置像 SecurityManager 这样的简单对象图。请注意,Shiro 还支持 Spring XML 配置和其他替代方案,但我们将在此处介绍 INI。
下面清单 2 中的示例显示了基于 INI 配置 Shiro 的最简单示例。
清单2: 使用 INI 配置 Shiro
[main]
cm = org.apache.shiro.authc.credential.HashedCredentialsMatcher
cm.hashAlgorithm = SHA-512
cm.hashIterations = 1024
# Base64 编码(较少文本):
cm.storedCredentialsHexEncoded = false
iniRealm.credentialsMatcher = $cm
[user]
jdoe = TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJpcyByZWFzb2
asmith = IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbXNoZWQsIG5vdCB
在清单 2 中,我们看到了将用于配置 SecurityManager 实例的示例 INI 配置。有两个 INI 部分:[main] 和 [users]。
[main] 部分是您配置 SecurityManager 对象和/或 SecurityManager 使用的任何对象(如领域)的地方。在此示例中,我们看到正在配置两个对象:
cm 对象,它是 Shiro 的 HashedCredentialsMatcher 类的一个实例。如您所见,cm 实例的各种属性是通过“嵌套点”语法配置的——这是清单 3 中所示的 IniSecurityManagerFactory 使用的一种约定,用于表示对象图导航和属性设置。
iniRealm 对象,它是 SecurityManager 用来表示以 INI 格式定义的用户帐户的组件。
[users] 部分是您可以指定静态用户帐户列表的地方 - 方便简单的应用程序或测试时。
出于本介绍的目的,了解每个部分的复杂性并不重要,重要的是要了解 INI 配置是配置 Shiro 的一种简单方法。有关 INI 配置的更多详细信息,请参阅Shiro 的文档。
清单3: 加载 shiro.ini 配置文件
import org.apache.shiro.SecurityUtils; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.util.Factory;
…
//1。加载 INI 配置
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");//2。创建 SecurityManager
SecurityManager securityManager = factory.getInstance();//3。使其可访问
SecurityUtils.setSecurityManager(securityManager);
在清单 3 中,我们在这个简单示例中看到了一个三步过程:
- 加载将配置 SecurityManager 及其构成组件的 INI 配置。
- 根据配置创建 SecurityManager 实例(使用代表工厂方法设计模式的 Shiro 的工厂概念)。
- 使应用程序可以访问 SecurityManager 单例。在这个简单的示例中,我们将其设置为 VM-static 单例,但这通常不是必需的 - 您的应用程序配置机制可以确定您是否需要使用静态内存。
Realm
Shiro 的第三个也是最后一个核心概念是Realm。Realm 充当 Shiro 和应用程序安全数据之间的“桥梁”或“连接器”。也就是说,当需要与安全相关数据(如用户帐户)进行实际交互以执行身份验证(登录)和授权(访问控制)时,Shiro 从为应用程序配置的一个或多个领域中查找其中的许多内容。
从这个意义上说,Realm 本质上是一个特定于安全的DAO:它封装了数据源的连接细节,并根据需要使相关数据对 Shiro 可用。配置 Shiro 时,您必须指定至少一个 Realm 用于身份验证和/或授权。可以配置多个 Realm,但至少需要一个。
Shiro 提供开箱即用的 Realms 以连接到许多安全数据源(也称为目录),例如 LDAP、关系数据库 (JDBC)、文本配置源(如 INI 和属性文件)等等。如果默认的 Realms 不能满足您的需求,您可以插入自己的 Realm 实现来表示自定义数据源。下面的清单 4 是配置 Shiro(通过 INI)以使用 LDAP 目录作为应用程序领域之一的示例。
清单 4: 连接到 LDAP 用户数据存储的示例领域配置片段
[main]
ldapRealm = org.apache.shiro.realm.ldap.JndiLdapRealm
ldapRealm.userDnTemplate = uid={0},ou=users,dc=mycompany,dc=com
ldapRealm.contextFactory.url = ldap://ldapHost:389
ldapRealm.contextFactory.authenticationMechanism = DIGEST-MD5
现在我们已经了解了如何设置基本的 Shiro 环境,让我们来讨论一下作为开发人员的您将如何使用该框架。