第四节 Shiro权限管理

网友投稿 582 2022-11-16

第四节 Shiro权限管理

第四节 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 getYourPermissionByUsernameFromDB(String username) { return Arrays.asList("code:insert", "code:update"); }

三、验证你的权限信息

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 factory = new IniSecurityManagerFactory("classpath:shiro.ini"); SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(yourInputUsername, yourInputPassword); //调用自定义Realm的doGetAuthenticationInfo方法进行认证操作 subject.login(token); //返回当前shiro环境的门面 return subject; }

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 getYourPermissionByUsernameFromDB(String username) { return Arrays.asList("code:insert", "code:update"); }}

运行结果:

四、源码-

----------------------------------------------------分割线-------------------------------------------------------

下一篇:​​第五节 授权过程源代码追踪​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:编写一个简单的智能合约
下一篇:第十节 Shiro集成SSM框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~