Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人愈来愈多,由于它至关简单,对比Spring Security,可能没有Spring Security作的功能强大,可是在实际工做时可能并不须要那么复杂的东西,因此使用小而简单的Shiro就足够了。对于它俩到底哪一个好,这个没必要纠结,能更简单的解决项目问题就行了。redis
Shiro能够很是容易的开发出足够好的应用,其不只能够用在JavaSE环境,也能够用在JavaEE环境。Shiro能够帮助咱们完成:认证、受权、加密、会话管理、与Web集成、缓存等,在此我仅仅介绍咱们公司使用的认证、受权、加密功能,对于其余功能,小伙伴能够发挥一下自学能力呦数据库
身份认证/登陆,验证用户是否是拥有相应的身份;编程
受权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能作事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具备某个权限;小程序
加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;微信小程序
主体,表明了当前“用户”,这个用户不必定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;全部Subject都绑定到SecurityManager,与Subject的全部交互都会委托给SecurityManager;能够把Subject认为是一个门面;SecurityManager才是实际的执行者;缓存
至关于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心脏;全部具体的交互都经过SecurityManager进行控制;它管理着全部Subject、且负责进行认证和受权、及会话、缓存的管理安全
域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它须要从Realm获取相应的用户进行比较以肯定用户身份是否合法;也须要从Realm获得用户相应的角色/权限进行验证用户是否能进行操做;能够把Realm当作DataSource,即安全数据源。微信
token至关于一个令牌,是将用户的一些信息(如帐号、密码、等)通过散列而后生成一个无心义的字符串保存在数据库或者redis,散列不可逆,用户登陆时只能经过从新散列而后获得串和数据库中的串作比较,看是否相同断定帐号密码是否正确网络
相信看完上面的工做流程图你们必定会产生一个疑问-->为何要realm?请看下文分析。。。。
shiro做为一个安全受权框架,对于用户安全登陆上,怎样的用户是安全的?怎怎样的用户是能够进入的?样的用户该拥有什么样的权限?相信这些只有开发者才知道,realm正是shiro留给开发者用于自定义用户登陆验证和受权认证的一个类,咱们能够经过实现Realm接口建立一个自定义的realm类,用于自定义用户登陆验证方式(AuthenticationInfo来完成)和受权验证(AuthorizationInfo来完成)app
相信你们经过上面的讲解对shiro已经有了一些基本的了解,那么接下来我将经过咱们公司封装的shiro框架为例,向你们揭秘登陆和受权功能
经过查看代码,咱们知道这个token来自于请求域,来自于用户填写的信息
boolean loginSuccess = this.login(new Token(token));
将得到的token传入到一个login方法中,接下来让咱们顺着这里往下走,来到了另外一个login,里面有这么一句-->subject.login(token);
在这个方法里面咱们能够发现这么一句-->info = authenticate(token);,咱们能够发现这就是在间接地调用relam类里面的咱们自动以的验证方法
咱们会发现他是经过用户数据为key在redis中尝试获取有没有对应的value,来证实是否这个用户曾经注册过,或者帐号密码和一些信息是否正确
主体,即访问应用的用户,在Shiro中使用Subject表明该用户。用户只有受权后才容许访问相应的资源。
在应用中用户能够访问的任何东西,好比访问JSP页面、查看/编辑某些数据、访问某个业务方法、打印文本等等都是资源。用户只要受权后才能访问。
安全策略中的原子受权单位,经过权限咱们能够表示在应用中用户有没有操做某个资源的权力。即权限表示在应用中用户能不能访问某个资源,如:
访问用户列表页面
查看/新增/修改/删除用户数据(即不少时候都是CRUD(增查改删)式权限控制)
打印文档等等。。。
如上能够看出,权限表明了用户有没有操做某个资源的权利,即反映在某个资源上的操做允不容许,不反映谁去执行这个操做。因此后续还须要把权限赋予给用户,即定义哪一个用户容许在某个资源上作什么操做(权限),Shiro不会去作这件事情,而是由实现人员提供。
Shiro支持粗粒度权限(如用户模块的全部权限)和细粒度权限(操做某个用户的权限,即实例级别的),后续部分介绍。
角色表明了操做集合,能够理解为权限的集合,通常状况下咱们会赋予用户角色而不是权限,即这样用户能够拥有一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、CTO、开发工程师等都是角色,不一样的角色拥有一组不一样的权限。
即直接经过角色来验证用户有没有操做权限,如在应用中CTO、技术总监、开发工程师可使用打印机,假设某天不容许开发工程师使用打印机,此时须要从应用中删除相应代码;再如在应用中CTO、技术总监能够查看用户、查看权限;忽然有一天不容许技术总监查看用户、查看权限了,须要在相关代码中把技术总监角色从判断逻辑中删除掉;即粒度是以角色为单位进行访问控制的,粒度较粗;若是进行修改可能形成多处代码修改。
在程序中经过权限控制谁能访问某个资源,角色聚合一组权限集合;这样假设哪一个角色不能访问某个资源,只须要从角色表明的权限集合中移除便可;无须修改多处代码;即粒度是以资源/实例为单位的;粒度较细。、
Shiro支持三种方式的受权:
1.编程式:经过写if/else受权代码块完成:
Java代码
Subject subject = SecurityUtils.getSubject(); if(subject.hasRole(“admin”)) { //有权限 } else { //无权限 }
注解式:经过在执行的Java方法上放置相应的注解完成:
Java代码 收藏代码 @RequiresRoles("admin") public void hello() { //有权限 }
没有权限将抛出相应的异常;
JSP/GSP标签:在JSP/GSP页面经过相应的标签完成:
Java代码
<shiro:hasRole name="admin"> <!— 有权限 —> </shiro:hasRole>
这是我从公司一个勘察项目中截下的一段代码能够看到-->@RequiresRoles。。。。
它的意思就是后面的角色里只要用户有其中一个角色就可使用这个方法
咱们能够发现它先拿到一个userid,而后经过userid为key在redis中寻找value,而后将权限信息放入info返回,对此你们必定很好奇他在redis中拿了什么
咱们查看redis发现它拿了一个数字
以上,就是今天的所有内容。
增鑫
芦苇科技Java开发工程师
芦苇科技-广州专业软件外包服务公司
提供微信小程序、APP应用研发、UI设计等专业服务,专一于互联网产品咨询、品牌设计、技术研发等领域、
访问 www.talkmoney.cn 了解更多
万能说明书 | 早起日记Lite | 凹凸壁纸 | 言财