请求原谅比请求许可更容易
如何根据用户的账户和特权限制其特定权限?
引言
有些人认为先做后道歉比事先请求许可更好?(标题上的双关语请见谅)。在现代计算环境中,文件级别的权限在操作系统中非常重要。在日常生活中,我们大多数情况下不会直接与它们交互。我们大多数人都可以创建管理员帐户,但除了技术专家、IT 用户或高级用户之外,几乎不了解如何限制某个人的特定权限。那么,我们如何根据帐户和权限来限制某个人的特定权限呢?我将在下面用 VB.NET 解释如何更改文件级别的权限。
要求
- Dotnet framework 4.5 或更高版本
- Windows 7 操作系统或更高版本
- 时间:根据要添加或从文件中删除的权限数量,编码大约需要 30-45 分钟。但是,您完成此项目的速度可能会有所不同。
使用代码
I. 加载特定文件的用户
本教程的第一步是将具有特定文件权限的用户加载到列表框中。如图 1 所示,您可以看到具有文件权限的用户被检索并添加到 lstUsers。下面的示例 1 将用户加载到 lstUsers 中,以显示它检索了哪些用户。注意:检索到的用户可能会因您的系统而异。为了在本教程中演示,创建了一些测试用户并将其添加到文件中。
示例 1 – 加载到 lstUsers 列表框中的用户。
Private Sub BtnBrowse_Click(sender As Object, e As EventArgs) Handles BtnBrowse.Click
OpenFileDialog1.Title = "Get access control for file"
OpenFileDialog1.Multiselect = False
OpenFileDialog1.InitialDirectory = "C:\Users\Jeffery\Desktop"
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
filename = OpenFileDialog1.FileName
Dim fi As New FileInfo(OpenFileDialog1.FileName)
Dim fs As New FileSecurity fs = fi.GetAccessControl
Dim object1 As Type = Type.GetType("System.Security.Principal.NTAccount")
For Each AuthRule As FileSystemAccessRule In fs.GetAccessRules(True, True, object1)
lstUsers.Items.Add(AuthRule.IdentityReference.Value.ToString)
Next
End If
End Sub
图 1 – 检索用户并添加到 lstUsers 列表框。
II. 查看特定用户的权限
本教程的第二步是查看特定用户的权限。正如您在示例 2 中看到的,我选择了用户test,他的允许和拒绝权限会显示出来。请注意,test没有任何拒绝权限?这不是代码错误。事实上,他根本没有任何被撤销或拒绝的权限。在图 2 中,我展示了 lstUsers_SelectedIndexChanged 事件的代码,该事件显示了从列表中选择的特定用户的权限。
示例 2 - 选择特定用户图 2 - lstUsers_SelectedIndexChanged
Private Sub lstUsers_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstUsers.SelectedIndexChanged
user = ""
user = lstUsers.SelectedItem.ToString
Dim fi As New FileInfo(filename)
Dim fs As New FileSecurity fs = fi.GetAccessControl
Dim object1 As Type = Type.GetType("System.Security.Principal.NTAccount")
lstAllowPermissions.Items.Clear()
lstDenyPermissions.Items.Clear()
For Each AuthRule As FileSystemAccessRule In fs.GetAccessRules(True, True, object1)
If AuthRule.IdentityReference.Value.ToString = lstUsers.SelectedItem.ToString Then
Dim ACL_Type As String = ""
If AuthRule.AccessControlType.Equals(AccessControlType.Deny) Then
ACL_Type = "Deny"
Else
ACL_Type = "Allow"
End If
Dim permissions As String = ""
If (AuthRule.FileSystemRights And FileSystemRights.FullControl) = FileSystemRights.FullControl Then
permissions = "Full Control"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.Modify) = FileSystemRights.Modify Then
permissions = "Modify"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.ReadAndExecute) = FileSystemRights.ReadAndExecute Then
permissions = "Read And Execute"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.ListDirectory) = FileSystemRights.ListDirectory Then
permissions = "List Directory Contents"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.Read) = FileSystemRights.Read Then
permissions = "Read"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.ReadPermissions) = FileSystemRights.ReadPermissions Then
permissions = "Read Permissions"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.Write) = FileSystemRights.Write Then
permissions = "Write"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.WriteAttributes) = FileSystemRights.WriteAttributes Then
permissions = "Write Attributes"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.WriteData) = FileSystemRights.WriteData Then
permissions = "Write Data"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.Traverse) = FileSystemRights.Traverse Then
permissions = "Trasverse Folder"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.ReadAttributes) = FileSystemRights.ReadAttributes Then
permissions = "Read Attributes"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.ChangePermissions) = FileSystemRights.ChangePermissions Then
permissions = "Change Permissions"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
If (AuthRule.FileSystemRights And FileSystemRights.CreateFiles) = FileSystemRights.CreateFiles Then
permissions = "Create Files"
If ACL_Type = "Allow" And permissions <> "" Then
lstAllowPermissions.Items.Add(permissions)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
End If
If ACL_Type = "Deny" And permissions <> "" Then
lstDenyPermissions.Items.Add(permissions)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
End If
End If
End If
Next
End Sub
III.添加/删除权限
在本节中,我们添加和更改权限,但不将其设置在文件上。下一个代码部分将展示如何将新权限设置在文件上。在本节中,我们正在添加新的权限以允许或拒绝权限列表,这些权限将被设置在文件上。在图 3 中,根据在 cboACLType 列表框中选择的内容,将权限添加到允许或拒绝列表。在图 4 中,显示了用于删除当前显示的允许或拒绝权限的代码。注意:在更改为下一个用户之前,必须删除该权限,否则更改可能会丢失。要删除项目,请在列表框中取消选中它,然后单击“删除权限”。
图 3 - 添加新的允许或拒绝权限
Private Sub BtnAdd_Click(sender As Object, e As EventArgs) Handles BtnAdd.Click
If cboACLType.SelectedItem = "Allow" Then
If lstAllowPermissions.Items.IndexOf(cboPermissionList.SelectedItem) = -1 And filename <> "" And lstUsers.SelectedIndex <> -1 Then 'filename must be something or a files properties have not been loaded
lstAllowPermissions.Items.Add(cboPermissionList.SelectedItem.ToString)
lstAllowPermissions.SetItemChecked(lstAllowPermissions.Items.Count - 1, True)
AllowPermissions.Add(lstAllowPermissions.Items.Item(lstAllowPermissions.Items.IndexOf(cboPermissionList.SelectedItem.ToString)))
End If
ElseIf cboACLType.SelectedItem = "Deny" Then
If lstDenyPermissions.Items.IndexOf(cboPermissionList.SelectedItem) = -1 And filename <> "" And lstUsers.SelectedIndex <> -1 Then
lstDenyPermissions.Items.Add(cboPermissionList.SelectedItem.ToString)
lstDenyPermissions.SetItemChecked(lstDenyPermissions.Items.Count - 1, True)
DenyPermissions.Add(lstDenyPermissions.Items.Item(lstDenyPermissions.Items.IndexOf(cboPermissionList.SelectedItem.ToString)))
End If
End If
End Sub
图 4 - 删除允许或拒绝权限
Private Sub BtnRemovePermissions_Click(sender As Object, e As EventArgs) Handles BtnRemovePermissions.Click
Dim count As Integer
count = lstAllowPermissions.Items.Count - 1
If count <> -1 Then
For allow = 0 To count
If allow = lstAllowPermissions.Items.Count Then
Exit For
End If
If lstAllowPermissions.GetItemCheckState(allow) = CheckState.Unchecked Then 'if an item is not checked then remove it
lstAllowPermissions.Items.RemoveAt(allow)
count = count - 1
End If
Next
If lstAllowPermissions.Items.Count > 0 Then
If lstAllowPermissions.GetItemCheckState(lstAllowPermissions.Items.Count - 1) = CheckState.Unchecked Then 'remove the last item seperately because it causes an error if I remove it first thing.
lstAllowPermissions.Items.RemoveAt(lstAllowPermissions.Items.Count - 1)
End If
End If
End If
count = 0
count = lstDenyPermissions.Items.Count - 1
If count <> -1 Then
For deny = 0 To count
If lstDenyPermissions.GetItemCheckState(deny) = CheckState.Unchecked Then 'if an item is not checked then remove it
lstDenyPermissions.Items.RemoveAt(deny)
End If
Next
If lstDenyPermissions.Items.Count > 0 Then
If lstDenyPermissions.GetItemCheckState(lstDenyPermissions.Items.Count - 1) = CheckState.Unchecked Then 'remove the last item seperately because it causes an error if I remove it first thing.
lstDenyPermissions.Items.RemoveAt(lstDenyPermissions.Items.Count - 1)
End If
Else
End If
End If
End Sub
在图 5+6 中,我使用拒绝和允许权限列表框的 selectedindexchanged 事件来根据选中的内容更改权限。
图 5 - 添加更改后的允许权限
Private Sub lstAllowPermissions_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstAllowPermissions.SelectedIndexChanged
AllowPermissions.Clear() 'clear the list of allowpermissions before adding the new allow permissions
For i = 0 To lstAllowPermissions.CheckedItems.Count - 1
AllowPermissions.Add(lstAllowPermissions.CheckedItems.Item(i).ToString)
Next
End Sub
图 6 - 添加更改后的拒绝权限
Private Sub lstDenyPermissions_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstDenyPermissions.SelectedIndexChanged
DenyPermissions.Clear() 'clear the list of all deny permissions before adding the new deny permissions
For i = 0 To lstDenyPermissions.CheckedItems.Count - 1
DenyPermissions.Add(lstDenyPermissions.CheckedItems.Item(i).ToString)
Next
End Sub
在示例 3 中,当您查看图片时,可以看到我为用户 test 添加了拒绝权限“列出目录内容”。要添加拒绝权限,我从组合框中选择了要拒绝的权限和“拒绝”,然后单击“添加权限”。注意:拒绝权限会覆盖本地文件的允许权限,因此如果权限被拒绝,则无需撤销该权限。
示例 3 - 为用户 test 添加拒绝权限“列出目录内容”。
IV.设置权限
在图 7 中,我为“设置权限”按钮调用 SetPermissions 函数。在图 8 中,SetPermissions 函数为我们在图 1 中选择的文件设置权限。
图 7 - “设置权限”按钮代码
Private Sub BtnSetPermissions_Click(sender As Object, e As EventArgs) Handles BtnSetPermissions.Click
If SetPermissions() = True Then
MsgBox("done!")
End If
End Sub
图 8 - SetPermissions 函数为我们选择的文件设置权限。
Public Function SetPermissions() As Boolean
Dim fi As New FileInfo(filename)
Dim fs As New FileSecurity
fs = fi.GetAccessControl
Dim object1 As Type = Type.GetType("System.Security.Principal.NTAccount")
Dim newrule As FileSystemAccessRule
If AllowPermissions.Count > 0 Then
For i = 0 To AllowPermissions.Count - 1
Select Case AllowPermissions.Item(i)
Case Is = "Read"
newrule = New FileSystemAccessRule(user, FileSystemRights.Read, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Write"
newrule = New FileSystemAccessRule(user, FileSystemRights.Write, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "List Directory Contents"
newrule = New FileSystemAccessRule(user, FileSystemRights.ListDirectory, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Create Files"
newrule = New FileSystemAccessRule(user, FileSystemRights.CreateFiles, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Read And Execute"
newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAndExecute, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Transverse Folder"
newrule = New FileSystemAccessRule(user, FileSystemRights.Traverse, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Full Control"
newrule = New FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Read Attributes"
newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAttributes, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Read extended Attributes"
newrule = New FileSystemAccessRule(user, FileSystemRights.ReadExtendedAttributes, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Modify"
newrule = New FileSystemAccessRule(user, FileSystemRights.Modify, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Append Data"
newrule = New FileSystemAccessRule(user, FileSystemRights.AppendData, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Change Permissions"
newrule = New FileSystemAccessRule(user, FileSystemRights.ChangePermissions, AccessControlType.Allow)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
End Select
newrule = Nothing
Next i
End If
newrule = Nothing
If DenyPermissions.Count > 0 Then
For i = 0 To DenyPermissions.Count - 1
Select Case DenyPermissions.Item(i)
Case Is = "Read"
newrule = New FileSystemAccessRule(user, FileSystemRights.Read, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Write"
newrule = New FileSystemAccessRule(user, FileSystemRights.Write, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "List Directory Contents"
newrule = New FileSystemAccessRule(user, FileSystemRights.ListDirectory, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Create Files"
newrule = New FileSystemAccessRule(user, FileSystemRights.CreateFiles, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Read And Execute"
newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAndExecute, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Transverse Folder"
newrule = New FileSystemAccessRule(user, FileSystemRights.Traverse, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Full Control"
newrule = New FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Read Attributes"
newrule = New FileSystemAccessRule(user, FileSystemRights.ReadAttributes, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Read extended Attributes"
newrule = New FileSystemAccessRule(user, FileSystemRights.ReadExtendedAttributes, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Modify"
newrule = New FileSystemAccessRule(user, FileSystemRights.Modify, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Append Data"
newrule = New FileSystemAccessRule(user, FileSystemRights.AppendData, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
Case Is = "Change Permissions"
newrule = New FileSystemAccessRule(user, FileSystemRights.ChangePermissions, AccessControlType.Deny)
fs.AddAccessRule(newrule)
File.SetAccessControl(filename, fs)
End Select
newrule = Nothing
Next i
End If
Return True
End Function
示例 4 - 展示拒绝权限如何应用于文件。
在示例 4 中,查看上面的“设备 (devices.txt 文件) 的权限条目”对话框如何仅显示拒绝权限“列出目录内容”,并且添加了一个新的拒绝规则?当“列表文件夹”权限更改为“拒绝”时,将添加新规则。但是,仅当我们单击 BtnSet Permissions(也称为“设置权限”按钮)然后转到下一个用户时,才会应用此规则。注意:这些是本地文件权限,不包括更改任何活动目录权限。
历史
- 2014 年 6 月 12 日 - 我在 TechNet wiki 上有一个副本,它不是原始文章(注意其他文章的内容是如何在本文章前一两个小时才发生变化的吗?此外,请注意我如何引用本文吗?它们都是我的文章):http://social.technet.microsoft.com/wiki/contents/articles/24808.better-to-ask-for-forgiveness-than-permission.aspx