Shiro简介:
Apache Shiro是Java的一个安全框架。功能强大,使用简单的Java安全框架,它为开发人员提供一个直观而全面的认证,授权,加密及会话管理的解决方案。
实际上,Shiro的主要功能是管理应用程序中与安全相关的全部,同时尽可能支持多种实现方法。Shiro是建立在完善的接口驱动设计和面向对象原则之上的,支持各种自定义行为。Shiro提供的默认实现,使其能完成与其他安全框架同样的功能,这不也是我们一直努力想要得到的吗!
Apache Shiro相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所以使用小而简单的Shiro就足够了。对于它俩到底哪个好,这个不必纠结,能更简单的解决项目问题就好了。
Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。这不就是我们想要的嘛,而且Shiro的API也是非常简单;
Shiro基本功能点:
Authentication:身份认证/登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;
Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;
Web Support:Web支持,可以非常容易的集成到Web环境;
Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;
Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;
Testing:提供测试支持;
Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;
Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。
Shiro认证过程:
如图所示,应用代码直接交互的对象是Subject,即Shiro的对外API核心。
Subject:主体,代表当前“用户”,该用户并不一定是具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫、机器人等;是一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以吧Subject认为一个入口,SecurityManager是实际的执行人。
SecurityManager:安全管理器,即所有与安全有关的操作都会与SecurityManager交互,且它管理着所有Subject,负责认证、授权、会话、缓存管理,是Shiro的核心,负责组件之间的交互,类似于SpringMVC框架中的前端控制器DispatcherServlet。
Realm:域,Shiro从Realm获取安全数据(如用户、角色、权限),即SecurityManager要验证用户身份,则需要从Realm获取响应的用户信息进行对比确认,包括身份信息、权限信息和角色信息。Realm类似于DataSource数据源,可以有多个。
应用代码通过Subject来进行用户认证和授权,Subject委托给了SecurityManager。SecurityManager注入Realm,并从中获取到合法用户的信息和权限,然后进行判断。用户的信息和权限需要开发人员注入到Realm中。
Shiro的控制精度:
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 |
http basic认证 |
user |
org.apache.shiro.web.filter.authc.UserFilter |
需要当前存在用户,不一定通过认证 |
logout |
org.apache.shiro.web.filter.authc.LogoutFilter |
注销登录,退出登录 |
port |
org.apache.shiro.web.filter.authz.PortFilter |
设定访问的端口号(不常用) |
perms |
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter |
表示用户必需已通过认证,并拥有响应权限才可以正常访问 |
roles |
org.apache.shiro.web.filter.authz.RolesAuthorizationFilter |
表示用户必需已通过认证,并拥有 admin 角色才可以正常访问 |
ssl |
org.apache.shiro.web.filter.authz.SslFilter |
表示需要安全的URL请求,协议为https(不常用) |
rest |
org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter |
根据请求方式来识别访问权限 |
eg: 关于shiro认证小例子
shiro-study
com.syy.shiro
1.0-SNAPSHOT
4.0.0
shiro-authentication
org.apache.shiro
shiro-core
1.4.0
junit
junit
4.12
public class AuthorizationTest {
SimpleAccountRealm simpleAccountRealm = new SimpleAccountRealm();
@Before
public void addUser(){
simpleAccountRealm.addAccount("mark","123456","admin","user");
}
@Test
public void testAuthentication(){
//1. 构建SecurityManager环境
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//1.2 将用户登录信息的数据源配置到SecurityManager环境中
defaultSecurityManager.setRealm(simpleAccountRealm);
//2. 主题提交认证请求
//2.1 SecurityUtils设置SecurityManager环境
SecurityUtils.setSecurityManager(defaultSecurityManager);
//2.2 获取shiro的Subject主体类
Subject subject = SecurityUtils.getSubject();
//2.2 创建token(用户信息)
UsernamePasswordToken token = new UsernamePasswordToken("mark","123456");
//2.3 主体提交认证
subject.login(token);
//2.4 是否认证通过
System.out.println("等录-是否认证通过:"+subject.isAuthenticated());
//2.5 验证用户是否具有admin角色;未授权异常:UnauthorizedException
//subject.checkRole("admin1");
subject.checkRoles("user","admin1");
//3.用户退出
subject.logout();
System.out.println("登出-是否认证通过:"+subject.isAuthenticated());
}
}
附练习源码