zoukankan      html  css  js  c++  java
  • ClickOnce部署(5):自定义安全权限

    今天我们来探讨一下在ClickOnce部署中如何严格控制应用程序的权限。

    演示应用

    为了在下文中能更好地演示,我们先要做一个测试项目。也为了显得简单易懂,我使用最常用且最常见的WinForm项目,这是地球上最丰富的物种。

    咱们做一个MD5的计算程序,这个应该够简单了吧?程序的功能是浏览打开一个文件,然后计算它的MD5,最后以字符串的形式输出。

    界面大致这样:

    其中用来输入文件名的文本框叫txtInput,用来显示计算结果的文本框叫txtOutput,为了方便输入文件名,我们在输入文本框的右侧放一个按钮,点击后通过OpenFileDialog来浏览文件。

    然后处理的代码如下:

    using System;

    ……

    using System.Windows.Forms;

    using System.Security.Cryptography;

    using System.IO;

     

    namespace md5ComputeApp

    {

    public partial class Form1 : Form

    {

    ……

     

    private void button1_Click(object sender, EventArgs e)

    {

    if (File.Exists(this.txtInput.Text) == false)

    {

    MessageBox.Show("靠,文件不存在,计算条毛啊。"); return;

    }

    MD5 md5 = new MD5CryptoServiceProvider();

    // 打开文件流

    FileStream fs = File.OpenRead(txtInput.Text);

    // 开始计算

    byte[] dataBuffer = md5.ComputeHash(fs);

    // 关闭流

    fs.Close();

    fs.Dispose();

    fs = null;

    // 转换为字符串

    StringBuilder bd = new StringBuilder();

    foreach (byte b in dataBuffer)

    {

    bd.Append(b.ToString("x2"));

    }

    // 显示结果

    this.txtOutput.Text = bd.ToString();

    }

     

    private void btnBrowser_Click(object sender, EventArgs e)

    {

    if (this.openFileDialog1.ShowDialog().Equals(DialogResult.OK))

    {

    this.txtInput.Text = this.openFileDialog1.FileName;

    }

    }

    }

    }

    好,运行一下,试试是否达到预期效果。如下图:

    OK,相当Nice,基本符合要求了。接下来我们就要对其进行部署了。

    完全信任权限

    部署我们肯定都会,而且前面我们也介绍过了。不过这一次我们重点是设置安全权限。为了保护我们的程序不被别有用心的人拿来干坏事,有时候我们没有必要让应用程序具有过高的权限。

    在项目属性窗口中,切换到"安全性"选项卡,勾选"启用ClickOnce安全设置"复选框,然后下面的几个单选项就变为可用状态。我们保持选中第一个,即"这是完全可信的应用程序"。最后保存。

    现在我们部署这个应用程序,相信大家都会了,就是切换到"发布"选项卡来完成,和前面所讲的方法一样。

    安装后我们看到程序正常运行了。

    部分可信任权限

    所谓部分可信任,就是相对我们前面的完全信任权限而言的,即应用程序不具备所有权限,比如,可能只允许应用程序访问D盘下的文件,或者说不允许应用程序进行反射操作等。

    要知道有哪些权限可以自定义也很简单,打开"对象浏览器"窗口找到System.Security.IPermission接口,然后我们查看实现它的类,以及这些类的子类,一层一层往下翻,那些命名为XXXPermission的类就是对应的权限了。除此之外,我们还会看到一些Attribute,如FileDialogPermissionAttribute,即它们的命名规律是XXXPermissionAttribute,我们只要找到这些规律,后面在配置权限时就好办了。

    现在,我们先不管权限如何配置,因为VS默认会为我们定义两个权限集。依旧,打开项目属性窗口,同样切换到"安全性"选项卡,这一次我们选择"部分信任的应用程序",如下图所示:

    在"要从中安装应用程序"下面的下拉列表框,为我们预定义了两种权限集,一种是内部Intranet,一种是广域Internet。我们可以根据具体情况来选。

    这里顺便告诉大家,这几个预定义的权限集在哪里。打开C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.5.1PermissionSets目录,你会看到有三个XML文件,和上面安全性配置上的"完全信任",部分信任中的"Internet"、"Intranet"相对应。我这里是.NET 4.5.1,具体看你安装的版本。

    FullTrust.xml——表示完全信任的权限配置。

    Internet.xml——表示Internet上的应用的权限配置。

    LocalIntranet.xml——本地Intranet的权限配置。

    我们可以打开这些XML文件看看里面有些什么。

    从中我们看到,每一项权限都是一个IPermission节点,这个IPermission是不是有点熟悉?对的,上面我们说过的一个接口,与权限配置有关的类都实现该接口。也就是说,自定义应用程序的权限,就是编写相应的XML节点。

    从MSDN的参考文档(参考地址:http://msdn.microsoft.com/ZH-CN/library/vstudio/ws1c2fch(v=vs.110).aspx)我们知道,权限集的配置在trustInfo元素下的security/applicationRequestMinimum/PermissionSet节点下,层次结构我们可以参考文档。

    好,我们来实战一下,这样讲还是觉得很抽象,再次打开项目属性,切换到"安全性"选项卡。选择部分信任选项,在"将要从中安装应用程序的区域"下面的下拉列表框中选择"自定义",这时候,右边的"编辑权限XML"按钮变为可用状态。如下图:

    我们不妨单击这个按钮,来查看XML文件,结合XML文件上的注释和文档说明,基础较好的朋友估计已经明白怎么用了。

    现在呢,不对XML文件进行任何修改,然后我们发布并安装应用程序。结果我们发现,应用程序没运行,手动到"开始"组中启动它也没有运行,这是很多朋友都遇到的问题,ClickOnce应用安装后不能运行。其实问题就出在权限上。刚才我们使用自定义权限集来发布应用程序,而我们又没有配置任何权限,就等于应用程序不具有任何权限,当然没法运行。

    回到项目属性窗口的"安全性"选项卡,点击"编辑权限XML"按钮。

    这时候就打开应用程序清单文件,我们找到trustinfo节点。找到PermissionSet节。如下图:

    注意PermissionSet节的ID要与defaultAssemblyRequest.permissionSetReference的值一致,这里已经为我们生成了Custom。

    我们要做的就是在PermissionSet下添加IPermission元素,这个元素怎么写呢?看文档。Version属性为1,我们只需设置class即可,需要赋给应用程序什么权限,就写上类的完整标识符,包括程序集和版本,公钥等。

    前面我为什么要介绍在对象浏览器中查看IPermission派生的类,就是为这里打下伏笔的。

    IPermission元素所属性并不只是class、version这几个,它可以和对应的类的属性进行合并,即XXXPermission和XXXPermissionAttribute的属性可以进行合并,如FileIOPermission类有个AllFiles属性,FileIOPermissionAttribute类有个Read属性,我们就可以把它们合起来用,即:

    <IPermission class=" System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" AllFiles="Read", Read="c:" />

    下面我们来为本示例的应用程序来配置一下权限,让它可以顺利地运行起来。

    首先,我们在PermissionSet元素下添加以下两个权限:

    <IPermission class="System.Security.Permissions.UIPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

    version="1"

    Unrestricted="true"/>

    <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

    Flags="Execution, BindingRedirects"/>

    这些类绝大部分位于mscorlib程序集内,我们进行复制就行了,至于说如何查看publickey等参数,我可以向大家说一种方法。打开VS的命令行工具窗口,当然,打开cmd也行,只要路径定义对就行了。输入以下命令:

    Gacutil /l mscorlib >>d:123.txt

    执行后就可以在d盘下的123.txt文件中输出结果,我们打开那个文本文件就可以把结果进行复制了。

    后面的processorArchitecture是指CPU架构,这个不用复制

    哦,还有,如果大家觉得去打开命令行工具麻烦,可以把常用的工具都集成到VS中,方法是在VS窗口中执行菜单【工具】-【外部工具】,随后弹出窗口,然后我们单击"添加"按钮。

    标题输入如"开发人员命令行工具",随便填,你自己知道什么意思就行。

    命令输入%ComSpec%,即cmd,记住首尾两个百分号不要掉了。

    参数输入/k ""C:Program Files (x86)Microsoft Visual Studio 12.0Common7ToolsVsDevCmd.bat""。注意是双重引号,你没看错。如下图:

    然后确定保存,以后你只需在VS中执行【工具】菜单,就会看到【VS命令行工具】项了,这样来打开就方便多了。

    好了,说了很多废话,还是回到我们的正题,上面我们为应用程序清单定义了两个权限:

    UIPermission:这是必须的,没有它应用程序界面就无法显示,你看它的名字就知道它的用途了。

    SecurityPermission:它的Flags属性可以是多个枚举值合并,在XML配置中我们可以用逗号分隔多个值,注意是英文的逗号,不解释。Execution是少不的,没有它就没法运行应用程序,BindingRedirects还是加上好一点,有时候读取配置文件时要用到。

    好,现在我们再次发布并安装应用程序,兴奋吧,程序终于运行起来了。如下图:

    不过,当我们单击右边的按钮浏览文件时,就发生错误了。

    这个错误也是没有权限造成的,回到项目,在清单文件上,我们继续添加可以操作文件对话框的权限。

    再添加以下两个权限:

    <IPermission class="System.Security.Permissions.FileDialogPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

    Access="Open"

    Unrestricted="true"/>

    <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

    All="Read"

    Unrestricted="true"/>

    FileDialogPermission的Access为Open表示允许使用打开文件对话框,但光这个还不够,因为我们在计算MD5时要读取文件的内容,所以,还要加一个FileIOPermission权限,All为Read表示程序对文件只有读的权限,不能写,对于我们的MD5计算器来说够了。Unrestricted设置为true把权限完全赋给程序以免应用程序在运行时申请权限失败。

    我们再次发布并安装应用程序,这一次看看能不能完成程序的功能。

    这回正常了,高兴一下吧。

    经过本节的演示,我们发现,完全自定义权限是相当麻烦的一件事,一般情况下我们不需要这样做,可以优先考虑不使用安全设置,或者使用预定义的权限。除非你确实需要严格控制,才会用自定义权限的方法。本节的演示也好让大家熟悉一下ClickOnce部署中分配权限的方法。

  • 相关阅读:
    【转】 Shiro 核心功能案例讲解 基于SpringBoot 有源码
    【转】 SpringData 基于SpringBoot快速入门
    【转】 Dubbo整合SpringBoot
    【转】 SpringBoot war包部署到Tomcat服务器
    【转】 SpringBoot使用Redis缓存
    【转】 SpringBoot统一异常处理
    【转】 SpringBoot创建定时任务
    【转】 SpringBoot 多环境配置
    js小数运算出现误差
    vue中组件的data为什么是一个函数
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/3379269.html
Copyright © 2011-2022 走看看