CAS(Code Access Security)
why?
CAS通过一下措施为调用有危险的APIs提供保护.
1.它保证未经确认的代码使用危险APIs时在调用堆栈上有恰当的权限.
2.它保证使用危险APIs的请求执行在安全代码并保存在AOT中.
3.它保证使用危险APIs的代码跟危险APIS运行在同一层.
感觉真像绕口令,就是把使用带有一定危险性的APIs的代码放在一个安全的地方,执行在一定的地方,提供一定的安全保障机制.
Axapta4.0的CAS机制把有危险性的API的调用都限定在了AOS上,所以不必费心劳力地去照顾客户端了.
how?
CAS必须有APIs的拥有者和使用者同时实现:
1.APIs的拥有者通过实现特定的许可类,并在该类上调用demand()方法来确保其安全性.
2.每一个API的使用者,必须通过调用许可类上的Asset()方法来获取调用危险APIs的许可.
上面的两步必须搞定,否则Application不会run的.
需要注意的是,这个机制不会帮忙验证传入到APIs的数据和或者参数,这个还是应该有API的使用者来保证.这个是当然的啦,CAS肯定不会帮忙验证这个的.
API 拥有者需要做的事情:
如果写了一个有一定危险性的API做为Application类,必须考虑它的脆弱性,考虑是否解决它,然后考虑用什么技术手段解决.
如果决定采用CAS来封装有一定危险性的APIs,必须完成一下步骤,同时,需要了解CAS对APIs做了怎样的扩展以及APIs的使用者需要如何配合完成封装.
1.继承类SysCodeAccessPermission创建一个密封类来保护APIs,注意,类中的变量是将要传递给APIs的参数.
final class SysTestCodeAccessPermission extends CodeAccessPermission
{
str _data;
}
public CodeAccessPermission copy()
{
return new SysTestCodeAccessPermission(_data);
}
private str data()
{
return _data;
}
public void new(str d)
{
super();
_data = d;
}
public boolean isSubsetOf(CodeAccessPermission _target)
{
SysTestCodeAccessPermission sysTarget = _target;
return _data == sysTarget.data();
}
public static void dangerousApi(str data)
{
SysTestCodeAccessPermission p = new SysTestCodeAccessPermission(data);
p.demand();
//Do dangerous stuff here.
}
下面是两个例子:
1.在TextBuffer类上应用CAS
TextBuffer用于处理任意的文本.用于管理任意的文本内容或者创建并进行处理文本文件.TextBuffer有各种字符串处理功能,简单的记事薄和文件接口.
如下方法在服务器端通过CAS使其危险性降低
public boolean fromFile(str filename, [int encoding=FileEncoding::AUTO])
public boolean toFile(str filename, [int encoding=FileEncoding::ACP])
下面的代码是在server端调用TextBuffer的示例.
server void MyServerFunction()
{
// Declare the CAS Permission object.
FileIOPermission fileIOPermission;
TextBuffer txtb = new TextBuffer();
// Assert that it is okay to read and write files and Clipboard
// because the content is coming from a static file name.
fileIOPermission = new FileIOPermission(filename, ‘rw’);
fileIOPermission.assert();
// From file will demand CAS permission (read)
txtb.fromFile("c:\\temp\\myfile.txt"); // Read text from file
// To clipboard will demand CAS permission (write)
txtb.toClipboard(); // Copy it to the clipboard
// To file will demand CAS permission (write)
txtb.toFile(("c:\\temp\\myfile.txt"); // Write text to file
}
DLL API运行X++代码直接调用Win32 DLL,两个类来实现这个功能,DLl和DLLFunction.DLL类的如下方法在server段被CAS所保护.
public void new(str filename)
server void MyServerFunction()
{
// Declare an interop permission of the right kind
InteropPermission dllPermission =
new InteropPermission(InteropKind::DllInterop);
DLL _DLL;
DLLFunction _chartCreate;
// assert that it is okay to use COM in this function
dllPermission.assert();
// construct operation demands CAS permission
_DLL = new DLL('cfx2032.dll');
// Method definition is not protected by CAS
_chartCreate = new DLLFunction(_DLL,'chart_Create');
_chartCreate.returns(ExtTypes::DWord);
_chartCreate.arg(ExtTypes::DWord,
ExtTypes::DWord,
ExtTypes::DWord,
ExtTypes::DWord,
ExtTypes::DWord);
// Invoke operation demands CAS permission
_windowhdl = _chartCreate.call(…);
// Optionally call revertAssert() to limit scope of assert.
CodeAccessPermission::revertAssert();
}

