第八讲 shiro位操作算法实现权限匹配(金庭波 QQ:14280784)

xiaoxiao2021-02-28  50

     《跟我学shiro》的第28页到30页,写得是使用位操作算法实现权限匹配,但是在验验过程中初学者会做得不太顺利,原因是教材中的代码不全。为了通俗易懂,我把这个实验过程全部笔录一遍,并说明原理。

先来认识几个单词:

authorizer        【奥得ruai热】  [经] 核准人,授权人,       在shiro中它是授权API的入口。

permission       【拍米生】       允许;批准,正式认可,认可,    在shiro中,它就是最后要得到的权限。resolver            【瑞肉喂】       下决心者,解决[答]问题者;溶媒;求解仪。

PermissionResolver    在shiro中,它是根据通配符解析成权限。

RolePermissionResolver    在shiro它是根据角色解析成权限。

    第一步:新建一个shiro_6的maven工程;

    第二步:修改成UTF-8编码;

    第三步:写pom.xml,内容如下:

<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>0.2.23</version> </dependency> </dependencies>

第四步:写src/main/resource下写shiro的配置文件:shiro.ini,内容如下:

[main] #授权入口 authorizer=org.apache.shiro.authz.ModularRealmAuthorizer #采用解析Bit字符串得到权限 permissionResolver=www.jintingbo.com.BitAndWildPermissionResolver authorizer.permissionResolver=$permissionResolver #根据角色得到角色的权限 rolePermissionResolver=www.jintingbo.com.MyRolePermissionResolver authorizer.rolePermissionResolver=$rolePermissionResolver securityManager.authorizer=$authorizer realm=www.jintingbo.com.MyRealm securityManager.realms=$realm

第五步:写BitAndWildPermissionResolver类

    看上面的配置,因为这个类不是shiro内部有的,所以要自己写。代码如下:

public class BitAndWildPermissionResolver implements PermissionResolver { public Permission resolvePermission(String permissionString) { if (permissionString.startsWith("+")) { return new BitPermission(permissionString); } return new WildcardPermission(permissionString); } }

注意这个类中有一个BitPermission类也可自己写。代码如下:

public class BitPermission implements Permission { private String resourceIdentify; private int permissionBit; private String instanceId; public BitPermission(String permissionString) { String[] array = permissionString.split("\\+"); if (array.length > 1) { resourceIdentify = array[1]; } if (StringUtils.isEmpty(resourceIdentify)) { resourceIdentify = "*"; } if (array.length > 2) { permissionBit = Integer.valueOf(array[2]); } if (array.length > 3) { instanceId = array[3]; } if (StringUtils.isEmpty(instanceId)) { instanceId = "*"; } } public boolean implies(Permission p) { //判断权限匹配 if (!(p instanceof BitPermission)) { return false; } BitPermission other = (BitPermission) p; if (!("*".equals(this.resourceIdentify) || this.resourceIdentify .equals(other.resourceIdentify))) { return false; } if (!(this.permissionBit == 0 || (this.permissionBit & other.permissionBit) != 0)) { return false; } if (!("*".equals(this.instanceId) || this.instanceId .equals(other.instanceId))) { return false; } return true; } }

第六步:写MyRolePermissionResolver类    

public class MyRolePermissionResolver implements RolePermissionResolver { public Collection<Permission> resolvePermissionsInRole(String roleString) { if("role1".equals(roleString)) { return Arrays.asList((Permission)new WildcardPermission("menu:*")); } return null; } }

第七步:写MyRealm,这一部分,教材上的代码不全,所以在这里加上它的验证部分。

public class MyRealm extends org.apache.shiro.realm.AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addRole("role1"); authorizationInfo.addRole("role2"); authorizationInfo.addObjectPermission(new BitPermission("+user1+10")); authorizationInfo.addObjectPermission(new WildcardPermission("user1:*")); authorizationInfo.addStringPermission("+user2+10"); authorizationInfo.addStringPermission("user2:*"); return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { String username = (String)token.getPrincipal(); //得到用户名 String password = new String((char[])token.getCredentials()); //得到密码 if(!"zhang".equals(username)) { throw new UnknownAccountException(); //如果用户名错误 } if(!"123".equals(password)) { throw new IncorrectCredentialsException(); //如果密码错误 } //如果身份认证验证成功,返回一个 AuthenticationInfo 实现; return new SimpleAuthenticationInfo(username, password, getName()); } public String getName() { return "aaa"; } public boolean supports(AuthenticationToken arg0) { return arg0 instanceof UsernamePasswordToken; } }

第八步:写测试运行的类

public class MyTest { private static void login(String configFile,String username,String password) {  //1、获取 SecurityManager 工厂,此处使用 Ini 配置文件初始化 SecurityManager  Factory<org.apache.shiro.mgt.SecurityManager> factory =  new IniSecurityManagerFactory(configFile);  //2、得到 SecurityManager 实例  并绑定给 SecurityUtils  org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();  SecurityUtils.setSecurityManager(securityManager);  //3、得到 Subject 及创建用户名/密码身份验证 Token(即用户身份/凭证) Subject subject = SecurityUtils.getSubject();  UsernamePasswordToken token = new UsernamePasswordToken(username,password);  subject.login(token);  public static void main(String[] args) { login("classpath:shiro.ini","zhang","123"); Subject subject = SecurityUtils.getSubject(); try{ subject.isPermitted("system:menu111:view"); System.out.println("OK!"); }catch (UnauthorizedException e){ System.out.println("没有这个权限!"); } }

}

第九步:运行

完毕

QQ:14280784 

转载请注明原文地址: https://www.6miu.com/read-2627961.html

最新回复(0)