zoukankan      html  css  js  c++  java
  • [AX]AX2012 code access permission

    假设你是个共用库API开发人员,你开发的API函数交由他人使用,你的一些API函数会在AOS上做一些危险的动作,比如修改一些服务器端的文件、调用WIN32函数,如果你的API被一些恶意代码利用,而不采取措施的话可能就造成了安全的漏洞,对此AX2012引入CodeAccessPermission(http://msdn.microsoft.com/EN-US/library/aa625357.aspx)检查权限。这不是AX2012才有的概念,早版本的AX已经支持,如何来保护我们的API防止被利用呢?来看看微软文档“Writing secure X++ code”(http://www.microsoft.com/en-us/download/details.aspx?id=21248)的一个例子(有所修改)。

    首先需要从CodeAccessPermission扩展一个自己的代码安全类: 

    final class SysTestCodeAccessPermission extends CodeAccessPermission
    {
        container _data;
    }
    public void new(container d)
    {
        ;
        super();
        _data=d;
    }
    private container data()
    {
        return _data;
    }
    public CodeAccessPermission copy()
    {
        return new SysTestCodeAccessPermission(_data);
    }
    public boolean isSubsetOf(CodeAccessPermission _target)
    {
        SysTestCodeAccessPermission sysTarget = _target;
        int i;
        boolean ret=true;
        ;
        
        //Check if the required permission in the given permission set
        for(i=1;i<=conLen(_data);i++)
        {
            if(!conFind(sysTarget.data(),conPeek(_data,i)))
            {
                ret=false;
                break;
            }
        }
        return ret;
    }

    在API函数中需要“Demand”运行代码所需要的权限,比如下面的dangerousRead需要“Read”权限,dangerousWrite需要“Write”权限:

    class MyAPIClass
    {
    }
    public static void dangerousRead(str data)
    {
        container c;
        SysTestCodeAccessPermission p;
        ;
        c=conIns(c,1,"Read");
        p= new SysTestCodeAccessPermission(c);
        p.demand();
    
        //Do dangerous stuff here.
        info("Read:" + data);
    }
    public static void dangerousWrite(str data)
    {
        container c;
        SysTestCodeAccessPermission p;
        ;
        c=conIns(c,1,"Write");
        p= new SysTestCodeAccessPermission(c);
        p.demand();
    
        //Do dangerous stuff here.
        info("Write:" + data);
    }

    在使用我们API的代码中,则要断言“assert”调用程序可用的权限:

    class TestMyAPIClass
    {
    }
    public server static void main(Args args)
    {
        str data="Test string";
        SysTestCodeAccessPermission permission;
        container c;
        ;
        c=conIns(c,1,"Read");
        c=conIns(c,1,"Write");
        permission=new SysTestCodeAccessPermission(c);
        permission.assert();
    
        //Read API
        MyAPIClass::dangerousRead(data);
    
        //Write API
        MyAPIClass::dangerousWrite(data);
    }

    如果注释掉“permission.assert()”或者“c=conIns(c,1,"Read");”、“c=conIns(c,1,"Write");”中的任何一行,我们都会得到类似“Request for the permission of type 'SysTestCodeAccessPermission' failed.”这样的异常。

    说实话,单就这个例子我们是看不出来有什么用,对于API的编写者无非是多了个permission.demand及在isSubsetOf中比较下权限,而对于API的使用者permission.assert一下就可用了。AX包含一些自带从CodeAccessPermission扩展的类,比如FileIOPermission、RunAsPermission大体上都只是在调用相应的危险代码前断言就行了。真的是这么简单吗?事实远比看到的复杂,在MSDN上找不到更多有用的说明,幸运的是我们知道.net也有code access security机制,在System.Security命名空间有个相同名称的CodeAccessPermission 类,这个.NET的类也有demand、Assert等方法,这是巧合吗?肯定不是,虽然不确定AX的code access security是不是在.NET的code access security基础上构建的,但可以推断两者的用途及原理应该差不多,理解了.net的CAS,也就容易理解AX的CAS了。如前所说,要搞懂.net的CAS也还真不容易,MSDN上很多概念都很抽象,还是给大家推荐一篇对此觉得很经典的文章吧(http://www.codeproject.com/Articles/5724/Understanding-NET-Code-Access-Security)。

    如果仔细阅读了上面的文章,回到这里简单总结一下:.net CAS是CLR的一种安全机制,使用各种各样的permission来保护危险代码防止非法调用,要授予使用的哪些permission是通过.net configuration tool来定义安全策略,在调用危险代码前可以使用C#的特性来明确定义危险代码所要求的权限,或者是在代码中动态的调用CodeAccessPermission或其扩展类的Demand()方法,它会在当前调用堆栈中从下到上逐级合并检查计算相应的权限集,我们能知道的是这是一个复杂的权限计算过程,如果结果权限集没有代码要求的权限,自然就是报错了。那Assert的作用呢,就是在做堆栈从下到上权限检查的时候,如果碰到Assert,就会使用Assert所明确的权限,而不再继续向堆栈上一级搜索计算权限。AX CodeAccessPermission的demand该和.NET差不多,它们作用类似,上面的代码就不难理解了。

    剩下的问题是如果我们可以随意断言(Assert),岂不是可以任意指定调用代码的权限?答案当然是否定的,在.NET平台,可以调用Assert的代码必须有SecurityPermission的Assertion权限(SecurityPermission设置Assertion Flag),这个自然是通过由.net runtime security policy通过configuration tool配置的。那么AX中调用CodeAccessPermission.assert()又是哪里来设置的呢?只能猜测同样也是.NET平台的安全策略,有知道的读者还望不吝赐教。

  • 相关阅读:
    【软件构造】第二章第一节 软件生命周期和版本控制(配置管理)
    【软件构造】第三章第三节 抽象数据型(ADT)
    【软件构造】第三章第二节 设计规约
    用python实现两个文本合并
    用python实现哈希表
    想要搭建项目 首选从概念理解(一)
    javascript调用rest地址,获取页面值
    ArcGIS Runtime SDK for Mac OS X使用示例
    ArcGIS Server网络分析模块问题汇总
    (ArcGIS Flex API)根据地图数据构建动态树
  • 原文地址:https://www.cnblogs.com/duanshuiliu/p/2696936.html
Copyright © 2011-2022 走看看