直接存取 Principal 物件
雖然使用命令式和宣告式要求來叫用以角色為基礎的安全性檢查,是檢查和強制識別和角色成員資格的主要機制,但也可能有一種狀況,您想要不建立使用權限物件而直接存取主體物件和與它關聯的識別物件來進行授權工作。 例如,如果您不想讓擲回的例外狀況成為驗證失敗的預設行為,您可能不想使用宣告式或命令式要求。 在此情況下,您可以在 System.Threading.Thread 類別上使用靜態 CurrentPrincipal 屬性來存取主體物件並呼叫它的方法。
取得主體物件之後,您可以根據如下列程式碼範例所示範的主體名稱,使用條件陳述式來控制對您程式碼的存取。
WindowsPrincipal MyPrincipal =
(WindowsPrincipal)Thread.CurrentPrincipal;
if (MyPrincipal.Identity.Name == "fred")
// Permit access to some code.
Dim MyPrincipal As WindowsPrincipal = _
CType(Thread.CurrentPrincipal, WindowsPrincipal)
If (MyPrincipal.Identity.Name = "fred") Then
' Permit access to some code.
End If
您也可以用程式設計的方式,在目前主體物件上呼叫 IsInRole 方法來檢查角色成員資格,如下列程式碼範例所示。
// Get the current identity.
WindowsIdentity MyIdent = WindowsIdentity.GetCurrent();
// Create a principal.
WindowsPrincipal MyPrincipal = new WindowsPrincipal(MyIdent);
// Check the role using a string.
if (MyPrincipal.IsInRole(@"BUILTIN\Administrators"))
{
Console.WriteLine("You are an administrator.");
}
else
{
Console.WriteLine("You are not an administrator.");
}
// Check the role using an enumeration.
if (MyPrincipal.IsInRole(WindowsBuiltInRole.Administrator))
{
Console.WriteLine("You are an administrator.");
}
else
{
Console.WriteLine("You are not an administrator.");
}
' Get the current identity.
Dim MyIdent As WindowsIdentity = WindowsIdentity.GetCurrent()
' Create a principal.
Dim MyPrincipal As New WindowsPrincipal(MyIdent)
' Check the role using a string.
If MyPrincipal.IsInRole("BUILTIN\Administrators") Then
Console.WriteLine("You are an administrator.")
Else
Console.WriteLine("You are not an administrator.")
End If
' Check the role using an enumeration.
If MyPrincipal.IsInRole(WindowsBuiltInRole.Administrator) Then
Console.WriteLine("You are an administrator.")
Else
Console.WriteLine("You are not an administrator.")
End If
在您想要存取應用程式定義的主體物件所特有的行為時,您可能會使用這個技術。 然而,大部分的情況中,您會根據識別或角色成員資格使用 PrincipalPermission 類別來控制存取您的程式碼。
下列程式碼範例會建立 WindowsPrincipal 物件和 WindowsIdentity 物件、設定它們為目前使用者,並根據主體的值進行安全性決策。 它不強制地或宣告式地使用 PrincipalPermission 物件,但以根據主體物件的值來產生存取決策。
using System;
using System.Security.Permissions;
using System.Security.Policy;
using System.Security.Principal;
using System.Threading;
public class Class1
{
public static int Main(string[] args)
{
// Set principal policy to get a WindowsPrincipal
// as the current principal so you have permission to get
// current user information.
AppDomain.CurrentDomain.SetPrincipalPolicy(
PrincipalPolicy.WindowsPrincipal);
// Get the current principal and put it into a principal object.
WindowsPrincipal myPrincipal = (Thread.CurrentPrincipal
as WindowsPrincipal);
// Check the name and see if the user is authenticated.
if (myPrincipal.Identity.Name.Equals(@"MYDOMAIN\myuser")
&& myPrincipal.Identity.IsAuthenticated.Equals(true))
{
Console.WriteLine("Hello {0}, you are authenticated!",
myPrincipal.Identity.Name.ToString());
}
else
{
Console.WriteLine("Go away! You are not authorized!");
}
// Use IsInRole to determine the role of the current user.
Array wbirFields = Enum.GetValues(typeof(WindowsBuiltInRole));
foreach (object roleName in wbirFields)
{
try
{
Console.WriteLine("{0}? {1}.", roleName,
myPrincipal.IsInRole((WindowsBuiltInRole)roleName));
}
catch (Exception)
{
Console.WriteLine("{0}: Could not obtain role for this RID.",
roleName);
}
}
return 0;
}
}
Imports System
Imports System.Security.Permissions
Imports System.Security.Policy
Imports System.Security.Principal
Imports System.Threading
Public Class Class1
Public Shared Sub Main()
' Set principal policy to get a WindowsPrincipal
' as the current principal so you have permission to get
' current user information.
AppDomain.CurrentDomain.SetPrincipalPolicy( _
PrincipalPolicy.WindowsPrincipal)
' Get the current principal and put it into a principal object.
Dim MyPrincipal As WindowsPrincipal = _
CType(Thread.CurrentPrincipal, WindowsPrincipal)
' Check the name and see if the user is authenticated.
If (MyPrincipal.Identity.Name.Equals("MYDOMAIN\myuser") _
And MyPrincipal.Identity.IsAuthenticated) Then
Console.WriteLine("Hello {0}, you are authenticated!", _
MyPrincipal.Identity.Name.ToString())
Else
Console.WriteLine("Go away! You are not authorized!")
End If
' Use IsInRole to determine the role of the current user.
Dim wbirFields As Array = _
[Enum].GetValues(GetType(WindowsBuiltInRole))
Dim roleName As Object
For Each roleName In wbirFields
Try
Console.WriteLine("{0}? {1}.", roleName, _
MyPrincipal.IsInRole(CType(roleName, _
WindowsBuiltInRole)))
Catch
Console.WriteLine( _
"{0}: Could not obtain the role for this RID.", _
roleName)
End Try
Next roleName
End Sub
End Class
如果目前的使用者為 MYDOMAIN\myuser,這個程式會將下列訊息顯示在主控台上。
Hello MYDOMAIN\myuser, you are authenticated!
然而,如果有任何其他使用者為目前使用者,程式會顯示下列訊息。
Go away! You are not authorized!
MyPrincipal.Identity.Name 中的值會顯示代表授權帳戶的網域和使用者名稱。 請注意,在 C# 中,字串 "MYDOMAIN\myuser" 的前面加上了位置符號 (@),因此不會將反斜線解譯為逸出字元 (Escape Character)。 雖然前面範例使用 WindowsIdentity 物件,您可以使用泛用物件輕易地產生類似的程式碼。 只需建立泛用物件的執行個體,傳遞您想要的值給它,並事後檢查物件的那些值。
請參閱
參考
System.Threading.Thread.CurrentPrincipal