react 前端框架如何驱动企业数字化转型与创新发展
632
2022-11-16
第四节 Shiro权限管理
一、授权的理解
你是谁,你是谁决定了你的身份是什么,你的身份决定了你能干什么。
这里牵扯出三种对象。
用户对象user:当前操作的用户。
角色对象role :表示一组 "权限操作许可权" 的集合。
权限对象permission:资源操作许可权。
例如,大宇(user)需要-(permission)一个高清无码的种子,需要VIP权限(role)。所以,本次-大致流程是先判断大宇是不是vip,然后再查看vip这种角色有没有-权限。
二、在自定义Realm中使用授权
进行授权操作的前提:用户必须通过认证。
在真实的项目中,角色与权限都存放在数据库中。为了快速上手,我们先创建一个自定义Realm,模拟它已经登录成功。直接返回一个登录验证凭证,告诉Shiro框架,我们从数据库中查询出来的密码是也是就是你输入的密码。所以,不管用户输入什么,本次登录验证都是通过的。
package shiro;public class PermissionRealm extends AuthorizingRealm ... //认证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String yourInputUsername = (String) token.getPrincipal(); String yourInputPassword = new String((char[]) token.getCredentials()); //默认要被验证的密码就是用户输入的密码,所以用户输入什么密码都是对的 String passwordFromDB = yourInputPassword; return new SimpleAuthenticationInfo(yourInputUsername, passwordFromDB, getName()); }
好了,接下来,我们要重写我们本小节的核心方法了。此方法的方法签名是:
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
用户认证凭证信息"。包装的是谁呢?没错,就是认证doGetAuthenticationInfo()方法的返回值的第一个参数yourInputUsername。你可以通过这个包装对象的getPrimaryPrincipal()方法拿到此值。就像下面的代码展示的那样。
//授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String yourInputUsername = (String) principals.getPrimaryPrincipal(); return null; }
既然在Realm中获取到了你的用户名,即登录凭证,那么下一步显然就是去数据库中查询你这个人是什么角色,有什么样的权限。假设你是一线开发人员,你对于公司代码所拥有的权限有:增加code:insert、修改code:update。用下面代码展示一下上述的论述。
//授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String yourInputUsername = (String) principals.getPrimaryPrincipal(); //构造一个授权凭证 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //通过你的用户名查询数据库,得到你的权限信息与角色信息。并存放到权限凭证中 info.addRole(getYourRoleByUsernameFromDB(yourInputUsername)); info.addStringPermissions(getYourPermissionByUsernameFromDB(yourInputUsername)); //返回你的权限信息 return info; } private String getYourRoleByUsernameFromDB(String username) { return "coder"; } private List
三、验证你的权限信息
OK,现在,你的权限信息已经被Shiro框架知晓了。下面我们就来使用Shiro的相关API来验证你的权限信息。
Subject这个门面又出现了!没错,几乎所有的Shiro框架的入口,都是这个门面对象。
第一步,先把我们的Realm配置到shiro.ini配置文件中。以后将不会使用这个shiro.ini文件,实际项目中会把shiro的相关配置使用Spring的配置文件集成。不过,你现在还不必关心那种配置方式,等到了与Spring集成的时候再说。
#shiro.ini 配置文件[main]#等号右边的shiro.PermissionRealm是包名+类名myRealm=shiro.PermissionRealmsecurityManager.realms=$myRealm
Shiro的Subject门面为我们提供了两套验证角色与权限的API接口。一组是以has开头的,它返回Boolean类型,如果你有此权限,那么返回true,反之返回false。另外一组是以check开头的,无任何返回值。它在检查你的角色信息或者权限信息的时候,如果你有此权限或者角色信息,它将不做任何操作,反之,则抛出一个异常,以中断当前程序的运行。
OK,知道了如何检查角色或者权限信息,让我们开始编写代码吧。
@Test public void testPermissionRealm() { Subject subject = login("anyUsername", "anyPassword"); //使用断言判断用户是否已经登录 Assert.assertTrue(subject.isAuthenticated()); //---------登录结束------------ //---------检查当前用户的角色信息------------ System.out.println(subject.hasRole("coder")); //---------如果当前用户有此角色,无返回值。若没有此权限,则抛 UnauthorizedException------------ subject.checkRole("coder"); //---------检查当前用户的权限信息------------ System.out.println(subject.isPermitted("code:insert")); //---------如果当前用户有此权限,无返回值。若没有此权限,则抛 UnauthorizedException------------ subject.checkPermissions("code:insert", "code:update"); } private Subject login(String yourInputUsername, String yourInputPassword) { //读取配置文件 Factory
package shiro;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import java.util.Arrays;import java.util.List;/** * @author jay.zhou * @date 2018/12/22 * @time 13:53 */public class PermissionRealm extends AuthorizingRealm { //认证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String yourInputUsername = (String) token.getPrincipal(); String yourInputPassword = new String((char[]) token.getCredentials()); //默认要被验证的密码就是用户输入的密码,所以用户输入什么密码都是对的 String passwordFromDB = yourInputPassword; return new SimpleAuthenticationInfo(yourInputUsername, passwordFromDB, getName()); } //授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String yourInputUsername = (String) principals.getPrimaryPrincipal(); //构造一个授权凭证 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //通过你的用户名查询数据库,得到你的权限信息与角色信息 info.addRole(getYourRoleByUsernameFromDB(yourInputUsername)); info.addStringPermissions(getYourPermissionByUsernameFromDB(yourInputUsername)); //返回你的权限信息 return info; } private String getYourRoleByUsernameFromDB(String username) { return "coder"; } private List
运行结果:
四、源码-
----------------------------------------------------分割线-------------------------------------------------------
下一篇:第五节 授权过程源代码追踪
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~