shiro简介与功能
- Apache Shiro 是 Java 的一个安全(权限)框架;
- Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE 环境,也可以用在 JavaEE 环境;
- Shiro 可以完成:认证、授权、加密、会话管理、Web 集成、缓存等
- Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
- Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
- Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境,也可以是 Web 环境的;
shiro架构
Shiro的核心概念有三个:Subject,SecurityManager 和 Realms。
- Subject:应用代码直接交互的对象是 Subject,也就是说 Shiro 的对外API 核心就是 Subject。Subject 代表了当前“用户”, 这个用户不一定是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫,机器人等;与 Subject 的所有交互都会委托给 SecurityManage,Subject 其实是一个门面,SecurityManager 才是实际的执行者;
subject被Shiro描述为一个主体,对于web系统来说可以理解为用户,这里让我们来引入一段话来体现我们的这种思想
在考虑应用安全时,你最常问的问题可能是“当前用户是谁?”或“当前用户允许做 X 吗?”。当我们写代码或设计用户界面时,问自己这些问题很平常:应用通常都是基于用户故事构建的,并且你希望功能描述(和安全)是基于每个用户的。所以,对于我们而言,考虑应用安全的最自然方式就是基于当前用户。Shiro 的 API 用它的 Subject 概念从根本上体现了这种思考方式。
在应用程序中,我们可以在任何地方来访问我们的当前的对象
import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;
...
Subject currentUser = SecurityUtils.getSubject();
- SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager 交互;且其管理着所有 Subject;可以看出它是 Shiro的核心,它负责与 Shiro 的其他组件进行交互,它相当于 SpringMVC 中DispatcherServlet 的角色;
一个应用只需要一个 SecurityManager,是一个单例对象。它的缺省实现是POJO,Shiro 里的其他组件也是一样。因此,可以用POJO兼容的任何配置机制进行配置:普通的Java代码、Spring xml、YAML、和 ini 文件等。基本上,能够实例化类和调用JavaBean兼容方法的任何配置形式都可以,下面我引入一段话来表示我们的相关的功能的功能的一段描述来增强我们对shiro的理解.
SecurityManager 是 Shiro 框架的核心,充当“保护伞”,引用了多个内部嵌套安全组件,它们形成了对象图。但是,一旦 SecurityManager 及其内部对象图配置好,它就会退居幕后,应用开发人员几乎把他们的所有时间都花在 Subject API 调用上。
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<property name="authenticator" ref="authenticator"></property>
<!--配置多realms的相关的信息-->
<property name="realms">
<list>
<ref bean="myRealm"/>
<ref bean="secondRealm"/>
</list>
</property>
</bean>
- Realm:Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色/权限进行验证用户是否能进行操作;
安全场景介绍
应用安全的四要素:认证、授权、会话管理、加密(这里主要是介绍认证和授权,回话和加密在后面的程序中直接使用,不过会有相关的注释,帮助读者更好的理解权限授权)。
认证
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);
可以看到,Shiro的操作及其简洁和自然,这也是Shiro 惯有的风格。在调用 login()方法后,SecurityManager 会收到AuthenticationToken,并将其发送给已配置的 Realm,执行必须的认证检查,以往我们手动去数据库中进行校验和匹配的时代已经过去了,这些所有的操作,全部由Shiro 帮我们自动完成。当数据经过Realm 的检查后发现无法匹配,那么Shiro 就会返回AuthenticationException 异常的子类,通过这些子类,我们可以精确的控制想要返回给用户的错误信息:
try {
currentUser.login(token);
} catch (IncorrectCredentialsException ice) {
…
} catch (LockedAccountException lae) {
…
}
…
catch (AuthenticationException ae) {…
}
授权
授权实质上就是访问控制,控制已认证的用户能够访问应用的哪些内容,如资源、页面等。
多数用户执行访问控制是通过 角色 + 权限 的概念来完成的。角色是所有用户个体的一个分组,如管理员、普通用户、商家等;而权限 则表示具体能够操作的行为,比如查询所有用户、删除某些用户、修改信息等等,是与具体应用资源直接挂钩的。
用户、角色和 权限三者往往通过 角色 来进行转换,用户和权限之间通常不进行直接绑定:
我们可以通过shiro的校验方法,来便捷地实现分支语句:
if ( subject.hasRole("administrator") ) {
// 显示‘Create User’按钮
} else {
// 按钮置灰?
}