Deny 메서드 사용
중요 |
---|
.NET Framework 버전 4에서 런타임 지원은 Deny, RequestMinimum, RequestOptional 및 RequestRefuse 권한 요청을 적용하기 위해 제거되었습니다.이러한 요청은 .NET Framework 4 이상을 기반으로 하는 코드에서 사용하면 안 됩니다.이 변경 내용 및 다른 변경 내용에 대한 자세한 내용은 .NET Framework 4의 보안 변경 내용을 참조하십시오. |
Deny를 호출하면 거부된 권한으로 지정된 리소스에 대한 액세스를 방지할 수 있습니다. 코드가 Deny를 호출한 다음 다운스트림 호출자가 거부된 권한을 요청하면 모든 호출자에게 해당 리소스에 액세스할 수 있는 권한이 있어도 보안 검사에서 실패합니다. 요청되고 있는 권한과 거부되고 있는 권한이 정확히 일치해야만 Deny가 효력이 있는 것은 아니며, 요청되는 권한이 거부되는 권한의 하위 집합일 필요도 없습니다. 그러나 두 권한의 교집합이 없으면 즉, 공통 부분이 없으면 Deny를 호출해도 아무 효력이 없습니다. Deny는 Assert를 수행하는 호출 스택의 하위 코드를 재정의할 수 없습니다. 호출 스택의 하위 코드가 Assert를 수행하면 하위 코드는 호출 스택의 상위 코드가 거부하는 리소스에 액세스할 수 있습니다.
코드에서 Deny를 호출하면 Deny로 인해 코드는 거부된 리소스에 액세스할 수 없으므로, 문제가 발생할 경우 책임을 질 필요가 없습니다. 그러나, Deny를 호출해도 다운스트림 호출자는 계속 보안 어설션을 수행할 수 있습니다.
다음 그림은 Deny를 사용할 때 일어나는 상황을 보여 줍니다. 어셈블리 A, B, C, D, E와 권한 P1에 대해 다음을 가정합니다.
P1은 C 드라이브에 있는 모든 파일을 읽을 수 있는 권한을 나타냅니다.
어셈블리 A, B, C, D, E에는 P1이 부여되어 있습니다.
메서드 F는 권한 P1에 요청을 삽입합니다.
메서드 C는 P1 클래스의 인스턴스를 만든 다음 P1의 Deny 메서드를 호출합니다.
메서드 A는 어셈블리 A에, 메서드 B는 어셈블리 B에 포함되는 식으로 각 메서드는 해당 어셈블리에 포함됩니다.
Deny 사용
메서드 C에서 Deny를 호출하면 P1에 대한 요청의 결과가 달라질 수 있습니다. 예를 들어, 메서드 A는 B를, B는 C를, C는 E를, E는 F를 호출한다고 가정해 봅니다. 메서드 F가 P1이 보호하는 리소스에 직접 액세스하므로 메서드 F는 P1의 Demand 메서드를 호출하거나 선언적 요청을 사용하여 P1에 대해 보안 검사를 호출합니다. 이 요청에 의해 공용 언어 런타임은 어셈블리 E부터 시작해서 호출 스택에 있는 모든 호출자의 권한을 검사합니다. 어셈블리 E에 P1 권한이 부여되었으므로 공용 언어 런타임은 계속해서 어셈블리 C의 권한을 검사합니다. 그러나 메서드 C는 P1을 거부하였으므로 메서드 E가 호출한 보안 검사는 이 시점에서 실패하며 SecurityException이 throw됩니다. 어셈블리 C와 호출자(어셈블리 A와 B)에 P1이 부여되었는지 여부에 상관없이 보안 검사에서 실패합니다. 메서드 C가 Deny를 호출했으므로 어셈블리 A와 B의 코드는 P1이 보호하는 리소스에 액세스할 수 없습니다.
다음 코드는 Deny 메서드를 사용하여 보안 검사를 재정의하는 선언적 구문을 보여 줍니다. 이 예제에서 ReflectionPermission 구문은 SecurityAction 열거형과 TypeInformation 속성의 설정 값을 지정합니다. TypeInformation은 해당 권한이 리플렉션을 통해 전용 멤버를 볼 수 있는 권한을 나타낸다는 것을 지정하기 위해 true로 설정되며 SecurityAction.Deny는 해당 권한을 거부하기 위해 전달됩니다. 지정할 수 있는 전체 값 목록은 ReflectionPermission에 대한 설명을 참조하십시오. 이 보안 선언을 사용하면 메서드는 리플렉션을 통해 형식의 전용 멤버를 읽을 수 없습니다.
Option Strict
Option Explicit
Imports System
Imports System.Security.Permissions
<ReflectionPermissionAttribute(SecurityAction.Deny, TypeInformation = true ")> Public Class
MyClass1
Public Sub New()
End Sub
Public Sub GetPublicMembers ()
' Access public members through reflection.
End Sub
End Class
using System;
using System.Security.Permissions;
[ReflectionPermissionAttribute(SecurityAction.Deny, TypeInformation = true)]
public class MyClass
{
public MyClass()
{
}
public void GetPublicMembers()
{
//Access public members through reflection.
}
}
다음 코드는 Deny 메서드를 사용하여 보안 검사를 재정의하는 명령적 구문을 보여 줍니다. 이 예제에서는 ReflectionPermission 개체가 선언되며, ReflectionPermissionFlag.TypeInformation가 생성자로 전달되어 현재 권한이 초기화됩니다. Deny 메서드가 호출되면 코드와 호출자는 리플렉션을 통해 전용 필드를 읽는 데 사용될 수 없습니다.
Option Explicit
Option Strict
Imports System
Imports System.Security.Permissions
Public Class MyClass1
Public Sub New()
End Sub
Public Sub ReadRegistry()
Dim MyPermission As New ReflectionPermission (ReflectionPermissionFlag.TypeInformation)
MyPermission.Deny()
' Access public members through reflection.
End Sub
End Class
using System;
using System.Security.Permissions;
public class MyClass {
public MyClass() {
}
public void ReadRegistry() {
ReflectionPermission MyPermission = new ReflectionPermission (ReflectionPermissionFlag.TypeInformation);
MyPermission.Deny();
// Access public members through reflection.
}
}
Deny를 사용할 때의 정식화 문제
단일 파일, 레지스트리 항목, URL 및 시스템 경로는 여러 개의 이름을 사용하여 나타낼 수 있기 때문에 FileIOPermission, RegistryPermission, WebPermission, UrlIdentityPermission, SiteIdentityPermission 및 EnvironmentPermission을 거부할 때는 매우 주의해야 합니다. 예를 들어, 단일 파일인 MyFile.log는 "c:\MyFile.log" 및 "\\MyMachineName\c$\MyFile.log"를 비롯한 여러 가지 방법으로 참조될 수 있습니다. "c:\MyFile.log"에 대한 액세스를 나타내는 권한을 만들고 코드에 대해 이 권한을 거부하면, 코드에서는 다른 경로인 "\\MyMachineName\c$\MyFile.log"를 사용하여 해당 파일에 여전히 액세스할 수 있습니다.
PermitOnly와 Deny를 함께 사용하면 정식화 문제를 방지할 수 있습니다. PermitOnly를 사용하면 리소스의 몇 가지 가능한 이름 중 하나만 지정할 수 있으며 다른 이름으로는 해당 리소스에 액세스하지 못할 수 있습니다. PermitOnly를 사용하여 리소스에 허용되는 이름을 하나 지정한 후 이 이름을 사용하여 리소스에 액세스하지 못하도록 하려면 Deny를 사용해야 합니다.
다음 코드에서는 Deny와 PermitOnly를 함께 사용함으로써 코드가 MyLog.log라는 리소스에 액세스하지 못하도록 합니다. 이 코드에서는 다른 모든 이름 또는 경로를 사용하여 리소스에 액세스하는 것도 막습니다.
<FileIOPermissionAttribute(SecurityAction.PermitOnly, All := "C:\ "), FileIOPermissionAttribute(SecurityAction.Deny, All := "C:\MyLog.log")>
[FileIOPermissionAttribute(SecurityAction.PermitOnly, All = @"C:\ ")]
[FileIOPermissionAttribute(SecurityAction.Deny, All = @"C:\MyLog.log")]