一头扎进Shiro-权限认证(授权)
2016-01-13 14:46
197 查看
权限认证(授权)
权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源。在权限认证中,最核心的三个要素是:权限,角色和用户;
权限,即操作资源的权利,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利;
角色,是权限的集合,一中角色可以包含多种权限;
用户,在 Shiro 中,代表访问系统的用户,即 Subject;
授权分为编程式授权、注解式授权、jsp标签授权。
编程式授权
基于角色的访问控制
基于权限的访问控制
注解式授权
@RequiresAuthentication要求当前Subject已经在当前的session中被验证通过才能被访问或调用。
@RequiresGuest要求当前的Subject是一个"guest",也就是说,他们必须是在之前的session中没有被验证或 被记住才能被访问或调用。
@RequiresPermissions("account:create")要求当前的Subject被允许一个或多个权限,以便执行注解的方 法。
@RequiresRoles("administrator")要求当前的Subject拥有所有指定的角色。如果他们没有,则该方法将不 会被执行,而且AuthorizationException异常将会被抛出。
@RequiresUser RequiresUser注解需要当前的Subject是一个应用程序用户才能被注解的类/实例/方法访问或 调用。一个“应用程序用户”被定义为一个拥有已知身份,或在当前session中由于通过验证被确认,或者在之前 session 中的'RememberMe'服务被记住。
Jsp标签授权(用户在Shiro中,代表访问系统的用户,即 Subject)
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
Guest标签:用户没有身份验证时显示相应信息,即游客访问信息;
User标签:用户已经身份验证/记住我登录后显示相应的信息;
Authenticated标签:用户已经身份验证通过,即Subject.login登录成功,不是记住我登录的。
notAuthenticated标签:用户没有身份验证通过,即没有调用 Subject.login 进行登录,包括记住我自动 登录的也属于未进行身份验证。
principal标签:显示用户身份信息,默认调用Subject.getPrincipal()获取,即Primary Principal。
hasRole标签:如果当前 Subject 有角色将显示body体内容。
lacksRole标签:如果当前Subject没有角色将显示body体内容。
hasAnyRoles标签:如果当前Subject有任意一个角色(或的关系)将显示body体内容。
hasPermission标签:如果当前Subject有权限将显示body体内容。
lacksPermission标签:如果当前Subject没有权限将显示body体内容。
这篇文章,我们主要讲解编程式授权的基于角色的访问控制和基于权限的访问控制。
基于角色的访问控制
首先我们在resources目录下创建shiro_role.ini文件,用于记录用户和角色信息。[users] java1234=123456,role1,role2 jack=123,role1上面我们定义用户名java1234,密码为123456,拥有role1和role2角色。用户名jack密码为123,拥有role1角色。
然后通过Subject的hasRole、hasRoles、hasAllRoles方法判断用户的角色
package com.tgb.shiro; import java.util.Arrays; import org.apache.shiro.subject.Subject; import org.junit.Test; import com.tgb.common.ShiroUtil; public class RoleTest { @Test public void testHasRole() { Subject currentUser = ShiroUtil.login("classpath:shiro_role.ini", "java1234", "123456"); System.out.println(currentUser.hasRole("role1") ? "有role1这个角色" : "没有role1这个角色"); // 每个角色进行判断 boolean[] results = currentUser.hasRoles(Arrays.asList("role1", "role2", "role3")); System.out.println(results[0] ? "有role1这个角色" : "没有role1这个角色"); System.out.println(results[1] ? "有role2这个角色" : "没有role2这个角色"); System.out.println(results[2] ? "有role3这个角色" : "没有role3这个角色"); // 判断是否同时有role1。role2角色 System.out.println(currentUser.hasAllRoles(Arrays.asList("role1", "role2")) ? "有role1、role2这两个角色" : "role1、role2这两个角色不全有"); currentUser.logout(); } }hasRole判断java1234是否拥有role1角色,hasRoles是分别判断java1234是否拥有role1、role2、role3角色,hasAllRoles判断java1234是否同时拥有role1和role2角色。
和hasRole类似的还有checkRole、checkRoles方法对用户角色进行判断。
基于权限的访问控制
首先我们在resources目录下创建shiro_permission.ini文件,用于记录用户、角色和权限信息。[users] java1234=123456,role1,role2 jack=123,role1
[roles]
role1=user:select
role2=user:add,user:update,user:delete
上面我们定义用户名java1234,密码为123456,拥有role1和role2角色;用户名jack密码为123,拥有role1角色。接着我们定义role1的权限为user:select,role2的权限为user:add,user:update,user:delete。
然后通过Subject的isPermitted、isPermittedAll方法判断用户拥有的权限
package com.tgb.shiro; import org.apache.shiro.subject.Subject; import org.junit.Test; import com.tgb.common.ShiroUtil; public class PermissionTest { @Test public void testIsPermitted() { Subject currentUser = ShiroUtil.login("classpath:shiro_permission.ini", "java1234", "123456"); System.out.println(currentUser.isPermitted("user:select") ? "有user:select这个权限" : "没有user:select这个权限"); boolean[] results = currentUser.isPermitted("user:select", "user:update", "user:delete"); System.out.println(results[0] ? "有user:select这个权限" : "没有user:select这个权限"); System.out.println(results[1] ? "有user:update这个权限" : "没有user:update这个权限"); System.out.println(results[2] ? "有user:delete这个权限" : "没有user:delete这个权限"); System.out.println(currentUser.isPermittedAll("user:select", "user:update") ? "有user:select,user:update这两个权限" : "没有user:select,user:update这两个权限"); currentUser.logout(); } }
isPermitted判断java1234是否拥有user:select权限,还可以分别判断java1234是否拥有user:select、user:update、user:delete权限,isPermittedAll判断java1234是否同时拥有user:select,user:update权限。
到此,我们已经讲解完关于shiro权限认证的编程式授权,下篇文章我们将继续讲解shiro权限认证的注解式授权和jsp标签授权。
相关文章推荐
- 没有继承Serializable导致JPA无法生成元模型(MetaModel)
- 实现打印机的共享
- Logger.getLogger()和LogFactory.getLog()的区别
- java读取文件
- 迎新年钜惠活动,错过等明年; 你学习,我打折!最高可减1500!让我们一起制定16年的学习计划!
- iOS下载图片之SDWebImage的研究与使用
- mac修改hostname
- 缩进动画Scaleanimation的一个小示例
- 1.1 U-Boot工作过程
- 自定义actionBar --RelativeLayout实现
- 查看Oracle的redo日志切换频率
- 程序员四门功课
- js 附件预览
- HJTextViewPlaceholder
- 视频去雾效果
- 网络编程之对象传递 Serializable接口
- phpstorm快速编辑模板技巧
- ♥CodeForces 609B-B. The Best Gift【组合数学】
- 使用断言NSAssert()调试程序错误
- Oracle字符替换