Shiro简介

杀马特。学长 韩版系。学妹 提交于 2020-02-09 18:31:09

之前在工作中有比较快速的学习过Shiro安全框架,但经过一年的荒废,已经不是很熟悉了,通过这个系列,深入研究和学习Shiro的一些知识,填补安全管理方面的知识漏洞。使我们在web 开发领域更具竞争力,不做只会CRUD的程序员!
一、Shiro介绍

Shiro是一个Java安全框架,执行身份验证、授权、密码、会话管理。Shiro是Apache 的一个开源项目,前身是JSecurity 项目,始于2003年初。

Shiro 可以为任何应用提供安全保障 - 从命令行应用、移动应用到大型网络及企业应用。

shiro 解决了应用安全的四要素:

    认证 - 用户身份识别,常被称为用户“登录”;
    授权 - 访问控制;
    密码加密 - 保护或隐藏数据防止被偷窥;
    会话管理 - 每用户相关的时间敏感的状态。

同时,Shiro另外支持了一些辅助特性:如 Web 应用安全、单元测试和多线程,它们的存在强化了上面提到的四个要素。
二、Shiro的优势

从 2003 年至今,框架选择方面的情况已经改变了不少,但今天仍有令人信服的理由让你选择 Shiro。其实理由相当多,Apache Shiro:

1、易于使用 - 易用性是这个项目的最终目标。应用安全有可能会非常让人糊涂,令人沮丧,并被认为是“必要之恶”【译注:比喻应用安全方面的编程。】。若是能让它简化到新手都能很快上手,那它将不再是一种痛苦了。

2、广泛性 - 没有其他安全框架可以达到 Apache Shiro 宣称的广度,它可以为你的安全需求提供“一站式”服务。

3、灵活性 - Apache Shiro 可以工作在任何应用环境中。虽然它工作在 Web、EJB 和 IoC 环境中,但它并不依赖这些环境。Shiro 既不强加任何规范,也无需过多依赖。

4、Web 能力 - Apache Shiro 对 Web 应用的支持很神奇,允许你基于应用 URL 和 Web 协议(如 REST)创建灵活的安全策略,同时还提供了一套控制页面输出的 JSP 标签库。

5、可插拔 - Shiro 干净的 API 和设计模式使它可以方便地与许多的其他框架和应用进行集成。你将看到 Shiro 可以与诸如 Spring、Grails、Wicket、Tapestry、Mule、Apache Camel、Vaadin 这类第三方框架无缝集成。

6、支持 - Apache Shiro 是 Apache 软件基金会成员,这是一个公认为了社区利益最大化而行动的组织。项目开发和用户组都有随时愿意提供帮助的友善成员。
三、核心概念

Shiro的核心概念有三个:Subject,SecurityManager 和 Realms。
3.1 Subject

subject 被Shiro 描述为一个主体,对于web应用来说,可以简单理解为用户。

这里我们来阐述一个Shiro设计的重要理念,即以主体为展开的安全体系构建。引用一段话:

在考虑应用安全时,你最常问的问题可能是“当前用户是谁?”或“当前用户允许做 X 吗?”。当我们写代码或设计用户界面时,问自己这些问题很平常:应用通常都是基于用户故事构建的,并且你希望功能描述(和安全)是基于每个用户的。所以,对于我们而言,考虑应用安全的最自然方式就是基于当前用户。Shiro 的 API 用它的 Subject 概念从根本上体现了这种思考方式。

在应用程序中,我们可以在任何地方获取当前操作的用户主体:

import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;
...
Subject currentUser = SecurityUtils.getSubject();

获得Subject 后,通过这个对象,我们可以对其进行绝大多数安全操作:登录、登出、访问会话、执行授权检查等。

Shiro 的api非常直观,它反映了开发者以“每个用户” 思考安全控制的自然趋势。
3.2 SecurityManager

Subject 的幕后推手是 SecurityManager,Subject 代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。

SecurityManager 是 Shiro 框架的核心,充当“保护伞”,引用了多个内部嵌套安全组件,它们形成了对象图。但是,一旦 SecurityManager 及其内部对象图配置好,它就会退居幕后,应用开发人员几乎把他们的所有时间都花在 Subject API 调用上。

一个应用只需要一个 SecurityManager,是一个单例对象。它的缺省实现是POJO,Shiro 里的其他组件也是一样。因此,可以用POJO兼容的任何配置机制进行配置:普通的Java代码、Spring xml、YAML、和 ini 文件等。基本上,能够实例化类和调用JavaBean兼容方法的任何配置形式都可以。

比如,通过ini文件进行配置:

[main]
cm = org.apache.shiro.authc.credential.HashedCredentialsMatcher
cm.hashAlgorithm = SHA-512
cm.hashIterations = 1024
# Base64 encoding (less text):
cm.storedCredentialsHexEncoded = false
 
iniRealm.credentialsMatcher = $cm

[main] 段落是配置SecurityManager 对象及其使用的其他任何对象(如 Realm) 的地方,在上面的示例中,我们看到了两个对象:

1、cm对象,是Shiro 的HashedCredentialsMatcher 类实例,cm 的各属性通过“嵌套点”语法进行配置。

2、iniRealm对象,被 SecurityManager 用来表示以INI 格式定义的用户账户。

然后,我们在Java代码中,可以轻而易举的获得 SecurityManager对象了:

//1. 装入 INI 配置
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
 
//2. 创建 SecurityManager
SecurityManager securityManager = factory.getInstance();
 
//3. 使其可访问
SecurityUtils.setSecurityManager(securityManager);

3.3 Realm

Realm 充当了 Shiro 与应用安全数据间的“桥梁”或者“连接器”。当切实与像用户帐户这类安全相关数据进行交互,执行认证(登录)和授权(访问控制)时,Shiro 会从应用配置的 Realm 中查找很多内容。

从某种意义上讲,Realm 实际上就是一个安全相关的 DAO:它封装了数据源的连接细节,并在需要时将相关数据提供给 Shiro。

注意:在配置Shiro 时,必须指定至少一个 Realm ,可以配置多个。

Shiro 内置了一些Realm ,支持多种数据源的连接,如JDBC、LDAP、INI文件的连接等。另外,可以自定义Realm 实现,方便个性化的应用场景。
四、典型的安全场景概述

应用安全的四要素:认证、授权、会话管理、加密。
4.1 认证

虽然有些武断,但是一般web 应用认证就是登录功能。也就是说,当用户使用应用进行认证时,他们就在证明他们就是自己所说的那个人。

这是一个典型的三步过程:

1、收集用户身份信息,成为当事人(principal),以及身份的支持证明,称为证书(Credential)。

2、将当事人和证书提交给系统。

3、如果提交的证书与系统期望的该用户身份(当事人)匹配,该用户就被认为是经过认证的,反之则被认为未经认证的。

Shiro 以简单直观的方式支持同样的流程。Shiro 有一套以Subject 为中心的API,几乎你想要用 Shiro 在运行时完成的所有事情都能通过与当前执行的 Subject 进行交互而达成。因此,要登录 Subject,只需要简单地调用它的 login 方法。传入表示被提交当事人和证书(在这种情况下,就是用户名和密码)的 AuthenticationToken 实例。

//1. 接受提交的当事人和证书:
AuthenticationToken token =
new UsernamePasswordToken(username, password);
 
//2. 获取当前 Subject:
Subject currentUser = SecurityUtils.getSubject();
//3. 登录:
currentUser.login(token);

U2FsdGVkX19G8utmO2M7S+7zNLb5elJT5/175W+4QS+Uq373OVHq+gduUnns14xn
F8ZugZ1w05FCgcCiV16IK9QbUuYYXnomutg0nfNIJFNeWYSHHd9Utr7B/4/9koHa
6XS2KY394rXuCTzjKs7dPD2UbOpmhZOTVp3oDh2KKFSfDq5pufK7MFHsTQt5MO1K
b+25tcUoY7OQudO3JPeXPxsrXFobS3F+W5QVjH5czuiDPUMdJja3E5MKmKXqLO54
fH4YZoYB+KbV2S9DVkikgYUaEQy+X3ozI97nNjRWYp7sLiab1p+SaWfNsBgcQiAq
OKJK9YD+wyV2PelrtRVytlOsAM8IWRV4s4Y4sTYalPzfJkOwPY0RmDHcE7SsQHwj
mh6aQlVEoEI9fEuhFGIfh1OF62rR1EzC/ri5pLnm44Xg6Cy0w1q0N+46/d/s+yzC
yT8WXLnUnxLGEQTIVnNIa5me9dLIW1sHGaP4Ywh9OKE=

可以看到,Shiro的操作及其简洁和自然,这也是Shiro 惯有的风格。在调用 login()方法后,SecurityManager 会收到AuthenticationToken,并将其发送给已配置的 Realm,执行必须的认证检查,以往我们手动去数据库中进行校验和匹配的时代已经过去了,这些所有的操作,全部由Shiro 帮我们自动完成。当数据经过Realm 的检查后发现无法匹配,那么Shiro 就会返回 AuthenticationException 异常的子类,通过这些子类,我们可

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!