引言
最近学习的shiro安全框架,打算把现有的知识梳理一下,下面我们来了解一下shiro这个强大且易用的Java安全框架。
Shiro介绍
Shiro是一个Java安全框架,可以帮助我们完成:执行身份验证、授权、密码、会话管理等。
Shiro是Apache 的一个开源项目,前身是JSecurity 项目,始于2003年初。
Shiro 可以为任何应用提供安全保障 - 从命令行应用、移动应用到大型网络及企业应用。
shiro 解决了应用安全的四要素
:
- 认证 - 用户身份识别,常被称为用户“登录”;
- 授权 - 访问控制;
- 密码加密 - 保护或隐藏数据防止被偷窥;
- 会话管理 - 每用户相关的时间敏感的状态。
同时,Shiro另外支持了一些辅助特性:如 Web 应用安全、单元测试和多线程,它们的存在强化了上面提到的四个要素。Shiro的API也是非常简单;其基本功能点如下图所示:
Authentication:身份认证/登录
,验证用户是不是拥有相应的身份;
Authorization:授权
,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理
,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密
,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web支持
,可以非常容易的集成到Web环境;
Caching:缓存
,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
记住一点,Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可。
Shiro包含了三个核心概念:Subject
,SecurityManager
和 Realms
。
- Subject:主体,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是其他的程序。Subject 代表了当前用户的安全操作。
- SecurityManager则管理所有用户的安全操作。它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
- Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
一般我们需要继承 org.apache.shiro.realm.AuthorizingRealm
,然后实现其中父类的2个抽象方法。
//登录及权限验证
public class MyRealm extends AuthorizingRealm {
//角色权限和对应权限添加
//Authorization授权,将数据库中的角色和权限授权给输入的用户名
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("执行授权逻辑");
//...
}
//用户身份验证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行认证逻辑");
//...
}
}
整体流程
用户通过Subject来进行认证和授权,而Subject又委托给SecurityManager,而SecurityManager又需要通过我们自定义的Realm来获取密码,权限等数据来进行校验和比对。
过滤器和权限拦截器
Shiro还提供了过滤器,可以配置我们的过滤规则
过滤器简称 | 对应的java类 | 参数概述 |
anon | org.apache.shiro.web.filter.authc.AnonymousFilter | 没有参数,表示可以匿名使用。 |
authc | org.apache.shiro.web.filter.authc.FormAuthenticationFilter | 表示需要认证(登录)才能使用,没有参数 |
authcBasic | org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter | 没有参数表示httpBasic认证 |
perms | org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter | 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割 |
port | org.apache.shiro.web.filter.authz.PortFilter | port[8081],当请求的url的端口不是8081是跳转到schemal |
rest | org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter | 根据请求的方法,相当于/admins/user/**=perms[user:method] |
roles | org.apache.shiro.web.filter.authz.RolesAuthorizationFilter | 参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割 |
ssl | org.apache.shiro.web.filter.authz.SslFilter | 没有参数,表示安全的url请求,协议为https |
user | org.apache.shiro.web.filter.authc.UserFilter | 没有参数表示必须存在用户,当登入操作时不做检查 |
logout | org.apache.shiro.web.filter.authc.LogoutFilter | 退出清除HTTPSession数据 |
我们也可以自定义实现过滤器,如果是授权相关,则继承org.apache.shiro.web.filter.authz.AuthorizationFilter
,如果是认证则继承AuthenticatingFilter
前端Shiro标签
标签名称 | 标签条件(均是显示标签内容) |
<shiro:authenticated > | 登录之后 |
<shiro:notAuthenticated > | 不在登录状态时 |
<shiro:guest > | 用户在没有RememberMe时 |
<shiro:user > | 用户在RememberMe时 |
<shiro:hasAnyRoles name=“abc,123” > | 在有abc或者123角色时 |
<shiro:hasRole name=“abc”> | 拥有角色abc |
<shiro:lacksRole name=“abc”> | 没有角色abc |
<shiro:hasPermission name=“abc”> | 拥有权限资源abc |
<shiro:lacksPermission name=“abc”> | 没有abc权限资源 |
<shiro:principal > | 默认显示用户名称 |
基本聊完之后我们来看看另一个安全框架与shiro的一些区别。
Spring security和Apache shiro比较
- shiro配置更加容易理解,容易上手,相比之下Spring security配置相对比较难懂。
- 在spring的环境下,security整合性更好。Shiro对很多其他的框架兼容性更好,号称是无缝集成。
-
Spring
以简单而闻名,但讽刺的是很多人发现安装Spring Security很难,然而Spring Security却有更好的社区支持 - Shiro提供的密码加密使用起来非常方便。
- Shiro 功能强大、且 简单、灵活。且不跟任何的框架或者容器绑定,可以独立运行。
实现参考下一篇:springboot整合shiro实现权限控制。