您的位置:首页 > 其它

.NET安全系列之二:独立存储区相关知识

2011-05-24 20:51 295 查看

http://www.cnblogs.com/lsxqw2004/archive/2009/01/21/1377915.html

接上一篇文章,本文详细CAS中一个相对独立的问题 – 独立存储区,说到独立存储区,为什么说它与CAS有关呢,因为这涉及到CLR需要赋予程序的一种特殊权限即访问独立存储区的权限。

独立存储区的作用

    在一般的程序中给其访问硬盘的权限是该应用程序受到巨大信任的标志。使用移动代码的应用程序只有很少一部分能够被授予如此高的信任级别,所
以大部分的移动代码是无法访问本地磁盘,然而大多数应用程序都需要持久保存一些数据(如用户的个性化设置),即将数据保存在硬盘上。不授权此类程序访问磁
盘会导致其无法正常工作,授权其访问硬盘又会面临一个安全问题。独立存储区的出现正是解决这个问题。

    针对移动代码可以授予其访问独立存储区的权限,这样就能限制它们只访问在硬盘上的为其保留的某个文件夹的权限。而且可以限制应用程序可以使
用的独立存储的大小。这样应用程序的移动代码对硬盘的访问就被限制在它自己的独立存储文件夹(不同的应用程序会有不同的文件夹),这个文件夹也被称作沙
箱。

    上述所说的这个沙箱文件夹的在计算机的位置及命名由多个因素决定:1. CLR、2. 程序集的标识及包含该程序集的应用程序域标识、3.

执行该应用程序的用户的标识。上述2、3两点中提到的标识被称作一个范围。每一种执行上下文(即一组不同的范围组合)对应一个独立存储文件夹,即一个应用
程序可以多个独立存储文件夹。应用程序每次在相同的上下文执行就会使用相同的文件夹。

System.IO.IsolatedStorage.IsolatedStorageFile类提供了一些静态方法来获得对应范围的文件夹。

GetUserStoreForAssembly()、GetMachineStoreForAssembly()、GetMachineStoreForDomain()及GetMachineStoreForApplication()。

最基本的访问独立存储文件夹的例子:

using
System.IO;

using
System.IO.IsolatedStorage;

class
Program {

static
void
Main()

{

//

获取当前用户帐户及程序集的独立存储目录

IsolatedStorageFile
isf =IsolatedStorageFile
.GetUserStoreForAssembly();

IsolatedStorageFileStream
isfs = new
IsolatedStorageFileStream
(

"pref.txt"
, FileMode
.Create, isf);

StreamWriter
sw = new
StreamWriter
( isfs );

sw.WriteLine("Put your preferences here..."
);

sw.Close();

}

}

 

应用场合



独立存储应用的场景很多,随着.NET2.0的广泛使用,ClickOnce的部署方式也日渐流行,部分传统的WinForm应用程序被以
ClickOnce方式部署,这样本是运行于本地计算机上的具有FullTrust权限的WinForm程序一下子变成了移动代码,从而权限收到限制,有
可能不能自由访问本地硬盘。这时候保存窗口大小、位置等信息的任务就要交由独立存储来完成,代码如下:

using
System;

using
System.Collections.Generic;

using
System.ComponentModel;

using
System.Data;

using
System.Drawing;

using
System.Text;

using
System.Windows.Forms;

using
System.IO.IsolatedStorage;

using
System.Runtime.Serialization;

using
System.Runtime.Serialization.Formatters.Binary;

using
System.IO;

 

namespace
WindowsApplication1

{

public
partial
class
Form1
: Form

{

public
Form1()

{

InitializeComponent();

}

 

private
void
Form1_Load(object
sender, EventArgs
e)

{

try

{

IsolatedStorageFile
isFile = IsolatedStorageFile
.GetStore(IsolatedStorageScope
.User | IsolatedStorageScope
.Assembly, null
, null
);

IsolatedStorageFileStream
isFileStream = new
IsolatedStorageFileStream
("Settings.isf"
, FileMode
.Open, isFile);

//

由二进制反序列化为类型

IFormatter
formatter = new
BinaryFormatter
();

//

获取窗体大小

this
.Size = (Size
)formatter.Deserialize(isFileStream);

//

获取窗体位置

this
.Location = (Point
)formatter.Deserialize(isFileStream);

if
(null
!= isFileStream)

isFileStream.Close();

if
(null
!= isFile)

isFile.Close();

}

catch
(System.IO.FileNotFoundException
ex)

{

MessageBox
.Show(ex.ToString());

}

}

 

private
void
Form1_FormClosing(object
sender, FormClosingEventArgs
e)

{

IsolatedStorageFile
isFile = IsolatedStorageFile
.GetStore(IsolatedStorageScope
.User | IsolatedStorageScope
.Assembly, null
, null
);

//

存储文件名为:
Settings.isf

IsolatedStorageFileStream
isFileStream = new
IsolatedStorageFileStream
("Settings.isf"
, FileMode
.OpenOrCreate, isFile);

//

序列话二进制文件

IFormatter
formatter = new
BinaryFormatter
();

//

存储窗体大小

formatter.Serialize(isFileStream, this
.Size);

//

存储窗体位置

formatter.Serialize(isFileStream, this
.Location);

if
(null
!= isFileStream)

isFileStream.Close();

if
(null
!= isFile)

isFile.Close();

}

}

}

代码出处

 

随着
Silverlight2
这种新型
RIA
应用程序的出现,独立存储又有了一个新的舞台,那就是用在
Silverlight
应用程序中,比较传统的
ASP.NET Web
应用程序中,信息被写入
Cookies
中,虽然
Silverlight
程序也可以操作
Cookies
,但是使用独立存储是一个更好的解决方案,独立存储不限制存储文件的类型,而且可用的空间较
cookie
更大(每个
Silverlight
应用),还可以在一定条件(用户允许)下扩充空间。
Silverlight
的独立存储是基于
.NET Framework
的独立存储建立的。

针对
Silverlight
独立存储的功能,在
TerryLee
的文章中摘录了部分方法(经简化),原文见此处


增加独立存储目录:

private
void
CreateDirectory()

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

if
(!store.DirectoryExists(directoryName))

{

store.CreateDirectory(directoryName);

}

}

}

写入文件:

private
void
CreateFile()

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

String
filePath = "a.txt"
;

 

IsolatedStorageFileStream
fileStream = store.CreateFile(filePath);

using
(StreamWriter
sw = new
StreamWriter
(fileStream))

{

sw.WriteLine(this
.txtFileContent.Text);

}

fileStream.Close();

}

}

读取文件:

private
void
ReadFile()

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

String
filePath = "a.txt"
;

String
Content;

if
(store.FileExists(filePath))

{

StreamReader
reader = new
StreamReader
(store.OpenFile(filePath, FileMode
.Open, FileAccess
.Read));

Content = reader.ReadToEnd();

}

}

}

删除目录和文件:

private
void
DeleteFile(string
filePath)

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

if
(filePath != ""
)

{

store.DeleteFile(filePath);

}

}

}

 

private
void
DeleteDirectory(string
dirPath)

{

if
(dir != ""
)

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

store.DeleteDirectory(dirPath);

}

}

}

获取目录与文件列表:

private
void
GetFilesLst(string
dirPath)

{

if
(dirPath == ""
)

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

String
[] files = store.GetFileNames();

}

}

else

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

String
[] files = store.GetFileNames(dirPath + "/"
);

}

}

}

 

private
void
GetDirectoriesLst()

{

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

String
[] directories = store.GetDirectoryNames("*"
);

}

}

增加用户存储空间,这个需要用户确认才能生效:

using
(IsolatedStorageFile
store = IsolatedStorageFile
.GetUserStoreForApplication())

{

long
newQuetaSize = 5242880;

long
curAvail = store.AvailableFreeSpace;

 

if
(curAvail < newQuetaSize)

{

store.IncreaseQuotaTo(newQuetaSize);

}

}

更多的还是参考
TerryLee
的文章啦!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息