一、shiro授权基础概念
(1)基于角色的访问控制
Shiro 提供了hasRole/hasRole 用于判断用户是否拥有某个角色/某些权限:
subject().hasRole("role1");//判断拥有角色:role1
subject().hasAllRoles(Arrays.asList("role1", "role2"));
subject().hasRoles(Arrays.asList("role1", "role2", "role3"));
Shiro 提供的checkRole/checkRoles 和hasRole/hasAllRoles 不同的地方是它在判断为假的情况下会抛出UnauthorizedException异常。
记住一点,shiro不提供角色和权限的维护,如果程序其他地方要用到权限或角色信息,或者如果需要在应用中判断用户是否有相应角色,用户是否有权限,就需要在相应的Realm中返回角色、权限信息,所有的信息都可以通过SecurityUtils.getSubject()来获取,包括session,host
(2)基于权限的访问控制
subject().isPermitted("user:create");//判断拥有权限:user:create
subject().isPermittedAll("user:update", "user:delete");//判断拥有权限:user:update and user:delete
subject().isPermitted("user:view");//判断没有权限:user:view
Shiro 提供了isPermitted 和isPermittedAll 用于判断用户是否拥有某个权限或所有权限,但失败的话,会抛出UnauthorizedException异常。
(3)权限的格式 “资源标识符:操作:对象实例ID” 即对哪个资源的哪个实例可以进行什么操作。其默认支持通配符权限字符串,“:”表示资源/操作/实例的分割;“,”表示操作的分割;“*”表示任意资源/操作/实例。
实际上还是不需要到实例级别的控制,如果到实例级别,数据量太大,会下降其性能。在本篇文章的鉴权实例中,权限的格式为“资源标识符:操作”
举个例子:
eg1: system:user:update,system:user:insert
这个表示用户拥有资源“system:user”的“update”和“insert”权限。
鉴权判断:
subject().checkPermissions("system:user:update", "system:user:insert");
subject().checkPermissions("system:user:update,insert"); //作用同上
注意:通过“system:user:update,insert”验证"system:user:update, system:user:insert"是没问题的,但是反过来是规则不成立。
eg2: 用户拥有资源“system:user”的“create”、“update”、“delete”和“view”所有权限。
system:user:*
subject().checkPermissions("system:user:*");
eg3: 对资源user的1 实例拥有view权限。
user:view:1
subject().checkPermissions("user:view:1");
二、shiro鉴权实例
前提:
紧接着上一篇文章shiro学习和使用实例(2)——登陆认证和授权,登陆认证通过后,清除掉原来的权限缓存,加上当前登陆账号的最新权限。接着就是登陆成功跳转到index(首页),此时,我们要对当前登陆账号鉴权。
思路:
账号登陆成功跳转到首页时,我们要对当前账号鉴权,通过判断账号是否具有某项操作的权限,来决定是否对当前登陆账号显示该操作的页面菜单、按钮或链接。当我们加载首页的时候,通过js将页面所有菜单的标识、权限发送到服务端,服务端调用shiro的isPermitted(String permission)从缓存中获取当前账号的权限信息(登陆成功后已将当前账号的最新权限信息放到缓存中了),如果缓存中没有,shiro会远程从数据库中获取。isPermitted(String permission)把从缓存中获取的权限和页面发送来的权限进行比较,将有无权限的结果返回到页面,通过回调函数决定菜单是否显示(有权限显示,无权限不显示)。
这是一种方案,也是我们接下来实例的内容。其实,还有粒度更小的权限限制方案,即对每个请求的方法加上权限判断,登陆账号具有这个权限,就可以请求此方法,得到响应,否则拒绝该请求。这个可以用shiro提供的注解来实现鉴权。
(1)、页面请求
首先要给所有的页面菜单唯一的资源标识,然后就是该菜单的操作(veiw,insert,update,,delete等),这样就满足了shiro的权限格式。例如系统中有“基础数据管理”这个菜单,则“com.isoftstone.yyp.portal.om.basic.data:veiw”。注意,这里的资源标识和操作要和授权时,加载到缓存中的权限要一致,也就是说,数据库保存的权限信息也必须是这个格式。
君子当权积福,小人仗势欺人。