Principal 개체에 직접 액세스
명령형 및 선언형 요청을 사용한 역할 기반 보안 검사가 ID 및 역할 멤버를 검사 및 시행하기 위한 기본적인 메커니즘이긴 하지만, Principal 개체와 이 개체에 관련된 Identity 개체에 직접 액세스하여 권한 개체를 만들지 않고도 권한 부여 작업을 수행할 수 있습니다. 예를 들어, 선언형 또는 명령형 요청을 사용하지 않으면 확인에 실패할 경우 기본 동작으로 예외가 throw되지 않게 할 수 있습니다. 이 경우 System.Threading.Thread 클래스에 대해 CurrentPrincipal 속성을 사용하여 Principal 개체에 액세스하고 해당 메서드를 호출할 수 있습니다.
Principal 개체를 가져온 다음에는 조건문을 사용하여 다음 코드 예제에서와 같이 Principal 이름에 따라 해당 코드에 대한 액세스 권한을 제어할 수 있습니다.
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
또한, 다음의 코드 예제에서와 같이 현재 Principal 개체에 대해 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
응용 프로그램 정의 Principal 개체의 관련 동작에 액세스하려고 할 때 이 방법을 사용할 수 있습니다. 하지만 대부분의 경우에는 PrincipalPermission 클래스를 사용하여 ID 또는 역할 멤버에 따라 해당 코드에 대한 액세스를 제어할 수 있습니다.
다음 코드 예제에서는 WindowsPrincipal 개체와 WindowsIdentity 개체를 만들고, 이 개체들을 현재 사용자로 설정한 다음 Principal의 값에 따라 보안을 결정합니다. 이 예제에서는 PrincipalPermission 개체를 명령형 또는 선언형으로 사용하지 않고, 그 대신 Principal 개체의 값에 따라 액세스를 결정합니다.
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" 문자열 앞에 @ 기호가 옵니다. 앞의 예제에서는 WindowsIdentity 개체를 사용하지만, 일반 개체를 사용하여 이와 비슷한 코드를 쉽게 만들 수 있습니다. 즉, 일반 개체의 인스턴스를 만들고, 여기에 원하는 값을 전달한 다음, 해당 개체의 값을 확인하면 됩니다.
참고 항목
참조
System.Threading.Thread.CurrentPrincipal