JVM学习笔记之反射权限控制ReflectPermission

1 篇文章 0 订阅

1.ReflectPermission介绍

ReflectPermission这个类通常是在反射中用来权限校验的,下面这张表格列举了各种权限及授予权限后带来的风险:

权限名称授权范围授权后带来的风险
suppressAccessChecks
可以屏蔽java原本对字段和方法的各种访问权限校验;不仅可以访问公共成员,还能访问default、protected以及private成员。可能被恶意代码访问到正常情况下无法得到的信息和方法
newProxyInPackage.{包名}
可以在代理类实现的非公共接口所在的包中创建一个代理对象恶意代码可能借此访问到原本无法方法访问的类,以及那些处于系统保护域内的动态类。从而破坏系统的安全性

里面就两个构造方法:

 public ReflectPermission(String name) {
        super(name);
    }
public ReflectPermission(String name, String actions) {
        super(name, actions);
    }

可以看到,构造方法其实调用的是父类BasicPermission的构造方法,我们去看看BasicPermission的构造方法做了些什么。

public BasicPermission(String name) {
        super(name);
        init(name);
    }

super(name)是给本地字段name赋值,重点是init(name),来看下具体代码:

/**
     * initialize a BasicPermission object. Common to all constructors.
     */
    private void init(String name) {
        if (name == null)
            throw new NullPointerException("name can't be null");

        int len = name.length();

        if (len == 0) {
            throw new IllegalArgumentException("name can't be empty");
        }

        char last = name.charAt(len - 1);

        // Is wildcard or ends with ".*"?
        if (last == '*' && (len == 1 || name.charAt(len - 2) == '.')) {
            wildcard = true;
            if (len == 1) {
                path = "";
            } else {
                path = name.substring(0, len - 1);
            }
        } else {
            if (name.equals("exitVM")) {
                wildcard = true;
                path = "exitVM.";
                exitVM = true;
            } else {
                path = name;
            }
        }
    }

代码不难看懂,第一种情况如果name是*或者以.*结尾说明是通配符模式,分别给wildcard和path赋值;第二种情况如果name等于“exitVM”就给wildcard、path、exitVM分别赋值;其他情况直接让path等于name。

2.ReflectPermission使用场景

这个类我们最常使用的场景是,在反射时候如果想使用某个非公有方法或者非公有构造器,需要先设置其可以访问,这时就要用到java.lang.reflect.AccessibleObject的setAccessible方法:

public void setAccessible(boolean flag) throws SecurityException {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
        setAccessible0(this, flag);
    }

这里的ACCESS_PERMISSION是一个私有的静态常量,实际上就是我们上面提到的suppressAccessChecks类型的RelectPermission。

static final private java.security.Permission ACCESS_PERMISSION =
        new ReflectPermission("suppressAccessChecks");

从上面的代码中我们可以看到涉及了SecurityManager,通过名字我们就可以知道这是安全管理器,具体什么是安全管理器可以看下一节介绍。然后是setAccessible0(this,flag)方法中会把本地属性override设置成true。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值