目录
- 1. shiro简介
- 2. shiro优势
- 3. 核心概念
- Subject
- SecurityManager
- Realm
- 工作原理示意图
- 4. 典型安全场景
- 4.1 认证
- 4.2 授权
- 5. shiro与web集成
- 5.1 集成
- 5.2 url过滤器
1.shiro简介
shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证、用户授权。spring中有spring security (原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。 shiro不依赖于spring,shiro不仅可以实现 web应用的权限管理,还可以实现c/s系统,分布式系统权限管理,shiro属于轻量框架,越来越多企业项目开始使用shiro。
应用场景:
- 在独立应用中使用
- 在web中使用
- 在spring框架中集成。
shiro 解决应用安全的四要素:
- 认证 - 用户身份识别,常被称为用户“登录”
- 授权 - 访问控制
- 密码加密 - 保护或隐藏数据防止被偷窥
- 会话管理 - 与用户相关的时间敏感的数据
2. shiro优势
- 易用: 相当于其他安全框架,shiro比较简单易用
- 广泛: 使用非常广泛,资料好找
- 灵活: 可以工作在很多工作环境,web,ejb,ioc等等
- web支持: 对web的支持好,允许你基于应用 URL 和 Web 协议(如 REST)创建灵活的安全策略,同时还提供了一套控制页面输出的 JSP 标签库
- 支持:应用广泛,是 Apache 软件基金会成员
3. 核心概念
Shiro的核心概念有三个:Subject,SecurityManager 和 Realms。
核心类:
Authentication
身份认证/登录,验证用户是不是拥有相应的身份;
Authorization
授权,即权限验证,验证某个已认证的用户是否拥有某个权限;
主要概念:
Subject
当前的操作用户:可以是人、爬虫、当前跟软件交互的东西。 在shiro当中我们可以统称"用户";
在代码的任何地方,都能轻易的获得Shiro Subject。
一旦获得Subject就能,登录、退出、访问会话、执行授权检查等
在应用系统中,使用shiro可以方便的获取当前操作的主体:
//获取当前主体
Subject currentUser =SecurityUtils.getSubject();
//判断主体是否具有指定角色。
subject.hasRole("administrator")
SecurityManager
SecurityManager管理所有用户的安全操作
引用了多个内部嵌套安全组件,是Shiro框架的核心
可以把它看成DispatcherServlet(springmvc)前端控制器。
用于调度各种Shiro框架的服务SecurityManager是通过java代码或配置文件生成,用来管理所有 用户的安全操作的对象,是单例的。
以ini配置文件为例:
// 1.装入 INI 配置
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2. 创建 SecurityManager
SecurityManager securityManager = factory.getInstance();
//3. 使其可访问
SecurityUtils.setSecurityManager(securityManager);
Realms
Realms是用户的信息认证器和用户的权限认证器
执行认证(登录)和授权(访问控制)时,Shiro会从应用配置的Realm中查找很多内容
Realm 可以理解为读取用户信息、角色及权限的 DAO
SecurityManager要验证用户身份与权限,那么它需要从Realm获取相应的信息进行比较以确定用户身份是否合法;
可以把Realm看成DataSource,即安全数据源。
选择其中的JdbcRealm,他的继承体系如下
注意:在配置Shiro 时,必须指定至少一个 Realm ,可以配置多个。
Shiro 内置了一些Realm ,支持多种数据源的连接,如JDBC、LDAP、INI文件的连接等。另外,可以自定义Realm 实现,方便个性化的应用场景。
4.典型的安全场景
应用安全的四要素:认证、授权、会话管理、加密。
4.1 认证
虽然有些武断,但是一般web 应用认证就是登录功能。也就是说,当用户使用应用进行认证时,他们就在证明他们就是自己所说的那个人。
这是一个典型的三步过程:
1、收集用户身份信息,成为当事人(principal),以及身份的支持证明,称为证书(Credential)。
2、将当事人和证书提交给系统。
3、如果提交的证书与系统期望的该用户身份(当事人)匹配,该用户就被认为是经过认证的,反之则被认为未经认证的。
Shiro 以简单直观的方式支持同样的流程。Shiro 有一套以Subject 为中心的API,几乎你想要用 Shiro 在运行时完成的所有事情都能通过与当前执行的 Subject 进行交互而达成。因此,要登录 Subject,只需要简单地调用它的 login 方法。传入表示被提交当事人和证书(在这种情况下,就是用户名和密码)的 AuthenticationToken 实例。
4.2 授权
授权实质上就是访问控制,控制已认证的用户能够访问应用的哪些内容,如资源、页面等。
多数用户执行访问控制是通过 角色 + 权限 的概念来完成的。角色是所有用户个体的一个分组,如管理员、普通用户、商家等;而权限 则表示具体能够操作的行为,比如查询所有用户、删除某些用户、修改信息等等,是与具体应用资源直接挂钩的。
用户、角色和 权限三者往往通过 角色 来进行转换,用户和权限之间通常不进行直接绑定:
5.shiro与web的集成
5.1 集成
1)配置文件shiro-web.ini
2)通过监听器EnvironmentLoaderListener读取配置文件,来创建相应的WebEnvironment
可通过shiroConfigLocations参数,指定shiro的配置文件
shiroConfigLocations 默认是“/WEB-INF/shiro.ini”IniWebEnvironment默认是先从/ WEB-INF/shiro.ini加载, 如果没有就默认加载 classpath:shiro.ini。
3) 配置过滤器,放在web.xml的最前面。该过滤器拦截所有的请求进行安全验证。
5.2 url过滤器
shiro通过url过滤器链功能支持特定的过滤规则。示例:
[urls]
/assets/** = anon
/user/signup = anon
/user/** = user
/rpc/rest/** = perms[rpc:invoke], authc
/** = authc
对于每一行,等号左边的值表示相对上下文的 Web 应用路径。等号右边的值定义了过滤器链 - 一个逗号分隔的有序 Servlet 过滤器列表,它会针对给出的路径进行执行。
shiro内置的安全过滤器:
过滤器 | 示例 | 作用 |
---|---|---|
anon | /admins/**=anon | 表示可以匿名使用,如登录页面 |
authc | /admins/user/**=authc | 表示需要认证才可使用 |
roles | /admins/user/**=roles[admin] | 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法 |
perms | /admins/user/**=perms[user:add:*] | perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:,user:modify:"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法 |
rest | /admins/user/**=rest[user] | 根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等 |
authcBasic | /admins/user/**=authcBasic | 没有参数表示httpBasic认证 |
过滤器 | 实现类 |
---|---|
anon | org.apache.shiro.web.filter.authc.AnonymousFilter |
authc | org.apache.shiro.web.filter.authc.FormAuthenticationFilter |
roles | org.apache.shiro.web.filter.authz.RolesAuthorizationFilter |
perms | org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter |
rest | org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter |
authcBasic | org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter |