首页 > 其他 > 详细

SecurityManager.checkRead

时间:2017-12-09 23:45:13      阅读:345      评论:0      收藏:0      [点我收藏+]
SecurityManager.checkRead

public void checkRead(String file) {
??????? checkPermission(new FilePermission(file,
??????????? SecurityConstants.FILE_READ_ACTION));//check 某个类对file是否有读权限
??? }

public void checkPermission(Permission perm) {
??????? java.security.AccessController.checkPermission(perm);
??? }

public static void checkPermission(Permission perm)
???????????????? throws AccessControlException
??? {
??????? //System.err.println("checkPermission "+perm);
??????? //Thread.currentThread().dumpStack();

??????? if (perm == null) {
??????????? throw new NullPointerException("permission can‘t be null");
??????? }

??????? AccessControlContext stack = getStackAccessControlContext();//
??????? // if context is null, we had privileged system code on the stack.
??????? if (stack == null) {
??????????? //此处略去debug
??????????? return;
??????? }

??????? AccessControlContext acc = stack.optimize();
??????? acc.checkPermission(perm);
??? }
}

public void checkPermission(Permission perm)
??????? throws AccessControlException
??? {
??????? boolean dumpDebug = false;

??????? if (perm == null) {
??????????? throw new NullPointerException("permission can‘t be null");
??????? }
???
??????? /*
???????? * iterate through the ProtectionDomains in the context.
???????? * Stop at the first one that doesn‘t allow the
???????? * requested permission (throwing an exception).
???????? *
???????? */

??????? /* if ctxt is null, all we had on the stack were system domains,
?????????? or the first domain was a Privileged system domain. This
?????????? is to make the common case for system code very fast */

??????? if (context == null)//这里context是一个ProtectionDomain数组,其实一个类只属于一个ProtectionDomain,一个ProtectionDomain可以对应多个类,但由于当一个类被调用时可能还有调用他的类,所以这些类对应的ProtectionDomain也要加入这个context,也就是说,线程中的调用链中的类的相关ProtectionDomain

都要 加入这个context,之所以这样是因为防止那些本来没有权限的类通过调用有权限的类从而访问不该他访问的资源

?????????? return;

??????? for (int i=0; i< context.length; i++) {
??????????? if (context[i] != null &&? !context[i].implies(perm)) {//从这可以看出来,只要有一个ProtectionDomain返回false,说明这个线程调用链上的某个类没有权限,所以就抛出异常 ?????????
??????????????? throw new AccessControlException("access denied "+perm, perm);
??????????? }
??????? }

??????? return;
??? }

public boolean implies(Permission permission) {

??????? if (hasAllPerm) {
??????????? // internal permission collection already has AllPermission -
??????????? // no need to go to policy
??????????? return true;
??????? }

??????? if (!staticPermissions &&
??????????? Policy.getPolicyNoCheck().implies(this, permission))
??????????? return true;
??????? if (permissions != null)
??????????? return permissions.implies(permission);//这个permissions就对应Permissions类,这个类里有个permsMap,他可以将各种Permission分类储存,比如

????FilePermission会放到FilePermissionCollection中,也就是和某一个类或某一系列类对应的FilePermission都会放的同一个FilePermissionCollection中。

??????? return false;
??? }

?public boolean implies(Permission permission) {
??????? // No sync; staleness -> skip optimization, which is OK
??????? if (allPermission != null) {
??????????? return true; // AllPermission has already been added
??????? } else {
??????????? synchronized (this) {
??????????????? PermissionCollection pc = getPermissionCollection(permission, //根据permission的类型找出对应的PermissionCollection

??????????????????? false);
??????????????? if (pc != null) {
??????????????????? return pc.implies(permission);
??????????????? } else {
??????????????????? // none found
??????????????????? return false;
??????????????? }
??????????? }
??????? }
??? }

说白了就是一组相关的类与一个ProtectionDomain关联,这个ProtectionDomain还关联了这组类所对应的permissions,这些信息是由java.policy文件定义的,当代码中需要查看对某一资源是否有权操作时,首先通过线程栈里的一组类找到一组相关的ProtectionDomain,然后通过ProtectionDomain得到这些类拥有的permissions,然后看看这些permissions里是否包含了要查看的资源的permission,有就ok,没有就抛异常。

SecurityManager.checkRead

原文:http://blog.51cto.com/2839840/2049074

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!