SimpleIsBest.NET

유경상의 닷넷 블로그
이 글은 오래된 전에 작성된 글입니다. 따라서 최신 버전의 기술에 알맞지 않거나 오류를 유발할 수 있습니다. 저자는 이 글에 대한 질문을 받지 않을 것입니다. 하지만 이 글이 리뉴얼 되면 이 글에 대한 질문을 하거나 토론을 할 수도 있습니다.

스마트 클라이언트 시리즈도 어느덧 6번째 글이 되었네요. 이번 포스트는 스마트 클라이언트에서 항상 걸림돌처럼 여겨지는 Code Access Security에 대해 몇 자 적어볼까 합니다. 내용이 방대하고 지루할 수 있는 것이라 저도 글 쓰는데 시간도 오래 걸렸을 뿐만 아니라, 저도 많이 지루했습니다. 시리즈 5번째 글이 올라오고 몇 달 만에 다음 글이 올라오다니...할말이 없습니다. 기다리신 분이 계셨다면(-_-;) 정말 죄송합니다.

더 이상 끌 수 없다는 초조감과 글이 점점 길어지는 바람에 마지막에는 날림으로 글을 마무리한 것 같아서 더욱 찜찜하네요. 너그럽게 용서해 주시기 바랍니다...


시리즈 목차

Smart Client (IV) : CAS Fundamentals

Code Access Security, (CAS; 맥주이름이 아니다. 오해 말기를....) 굳이 번역하자면 코드 액세스 보안(한글판 MSDN의 용어) 정도가 되는 이것은 닷넷 프레임워크와 함께 등장한 새로운 보안 모델이다. 오로지 닷넷 프레임워크에서만 적용되는 이 새로운 보안 모델에 대해 간략히 살펴보도록 하겠다. 여기서 다루는 내용은 CAS의 극히 일부분이다. 상세한 내용은 MSDN의 자료를 살펴보기 바란다. 찾아보기 조차 꺼려하는 독자를 위해 링크를 제공하겠지만, 이런 거 좋아하는 사람은 결코 고수가 될 수 없다. 스스로 MSDN에서 CAS에 대한 개념을 설명하는 글을 찾아 보기 바란다.

.NET Framework 개발자 가이드 : 코드 액세스 보안 (MSDN Online)

이미 지난 스마트 클라이언트 시리즈에서 CAS에 대해서는 여러 번 언급한 적이 있다. 그러면서도 구체적으로 CAS가 무엇이고 어떤 목적으로 사용되는지 설명하지는 않았다. 내용이 상당한 분량이기 때문에 별도의 포스트로 다루어야 했고, 글의 순서상 이제서야 겨우 CAS에 대해 다루게 된 것이다.

Why CAS ?

먼저 왜 CAS가 등장했는가를 살펴보도록 하겠다. CAS가 등장하게 된 이유를 알면 CAS를 이해하기 좀 더 쉽기 때문이다.

Windows의 기본적인 보안모델은 어떤 사용자가 어떤 작업을 수행하는데 권한이 있는가를 검사하고 이러한 액세스에 대한 감사(audit)를 수행하는 것이다. 예를 들어 Administraotr 가 C:\Boot.ini 파일을 쓸(Write) 수 있는가에 대한 권한을 검사하는 것이다. 대개 파일의 보안 대화 상자나 기타 Windows 보안에 대한 대화 상자를 살펴보면 이러한 방식임을 알 수 있을 것이다. 하지만 이러한 보안 모델은 인터넷이 발달하여 코드를 다운로드하고 바이러스와 웜이 창궐하는 작금의 상황에 부족하다는 것을 마이크로소프트가 인지한 것이다. 사실 Windows의 보안은 미 국방성이 요구하는 보안 수준을 상회하는 것임에도 불구하고 IT 환경이 빠르게 변화하는 것에 비하면 벌써 현실에 부응하지 못하는 것이 되고 있는 것이다.

어찌 되었건 CAS는 Windows의 기본 보안 모델에 "어떤 코드가" 라는 새로운 보안 체크를 추가한 것이다. 다시 말해서 Windows 가 기본적으로 수행하는 누가 어떤 작업을 수행할 수 있는가에 대한 검사에 추가하여, 누가 "어떤 코드를 통해" 어떤 작업을 수행하는가를 검사하겠다는 말이 되겠다. 사실 바이러스나 웜 같은 악성 코드를 생각해 보면 일단 다운로드 된 악성 코드들은 그 코드가 어디서 다운로드 되었건 관계 없이 현재 사용자가 누구인가에 따라서 그 권한을 부여 받게 된다. 예를 들어 웜 바이러스가 웹 페이지를 통해 다운로드 되었고 그 코드를 다운로드 받은 사용자가 시스템 관리자라면 웜 바이러스 역시 관리자의 권한을 갖게 된다는 것이다. 이 때문에 웜 바이러스는 자유롭게 시스템의 여러 파일을 감염시키거나 메일 주소를 읽는 행동을 취할 수 있다. 대개의 관리자 계정은 모든 파일을 액세스할 권한을 갖고 있기 때문이다.

CAS는 수행되는 코드가 어떤 코드인가에 따라서 권한에 제약을 주도록 되어 있다. 어떤 코드인가 검사한다는 것은 해당 코드가 파일 시스템 혹은 인터넷 사이트의 어디에서 로드 되었는가 혹은 누가 만든 코드인가에 따라서 갖는 권한이 다르다는 것이다. 예를 들어 인터넷에서 다운로드 받은 코드는 로컬 파일을 직접적으로 열(open) 수 없으며 파일 열기 대화 상자를 통해서만 가능하다. 이렇게 함으로써 시스템 관리자에 의해 바이러스 웜 코드가 수행되었을 지라도(고의건 속임수에 의하였건 관계 없이), 그것이 인터넷이나 기타 신뢰되지 않은 곳에서 로드 된 코드라면 권한에 제약이 가해지게 되는 것이다.

Fundamentals

왜 CAS가 등장했는가 간략히 살펴 보았으므로 이제 좀 더 상세하게 CAS를 뜯어 묵어 보겠다. 코드를 어떻게 그룹화하는지, 그리고 이렇게 그룹화된 코드를 위한 권한은 어떻게 할당하는지 살펴 보도록 하자.

Code Group & Membership Condition

닷넷 프로그램의 모든 코드에 각각 권한을 줄 수는 없는 노릇이다. 따라서 CAS는 코드들을 일련의 그룹으로 묶어서 권한을 할당한다. CAS에서 모든 코드들은 1개 이상의 코드 그룹(Code Group)이라는 것에 포함 된다. 앞서 말했던 "어떤 코드를 통해" 라는 문구에서 이 어떤 코드를 정의하는 것이 코드 그룹이 되겠다. 예를 들어 어셈블리(DLL 혹은 EXE)가 http://www.simpleisbest.net 에서 다운로드 되었다면, 이 코드는 Internet_Zone 이라는 코드 그룹에 포함되는 것이다(Internet_Zone 이라는 코드 그룹은 미리 정의된 표준 코드 그룹이다. 나중에 상세히 설명할 테니 쪼금만 기둘려라).

코드 그룹은 이 코드 그룹에 포함되는 코드들을 정의하는 멤버십 조건(Membership Condition)에 의해 포함 여부가 결정되게 된다(멤버쉽이 아니라 이게 표준어란다. ~십... 무슨 욕 같다. ㅡ,.ㅡ). 예를 들었던 Internet_Zone 이라는 코드 그룹은 영역 멤버십Zone membership)에 의해 Internet_Zone 코드 그룹에 포함된다. 멤버십 조건은 표준적으로 정의되어 있는 Zone 멤버십, Site 멤버십, URL 멤버십, Publisher 멤버십, Strong Name 멤버십 등등이 있다. 이들 중 가장 중요한 Zone, Site, URL 멤버십만을 여기서 살펴보도록 하겠다. 나머지는 MSDN 도움말과 .NET Configuration MMC를 참조하기 바란다.

Zone 멤버십 조건은 코드, 좀 더 구체적으로 말해 어셈블리를 로드 한 인터넷 영역에 의해 코드 그룹이 결정되는 것을 말한다. 인터넷 영역은 IE 에서 정의하는 그 인터넷 영역과 정확히 일치한다. IE가 정의하는 인터넷 영역들은 Internet, Local Intranet, Trusted Sites, Untrusted Sites, My Computer 5가지가 있다. 이들 영역 중 어느 영역에서 어셈블리를 로드 했는가에 따라서 그 어셈블리를 코드 그룹에 포함시키는 멤버십이 Zone 멤버십이다. Zone 멤버십을 사용하는 코드 그룹은 표준 코드 그룹으로서 My_Computer_Zone, LocalInteranet_Zone, Internet_Zone, Restricted_Zone, Trusted_Zone 이 존재한다(화면1 참조).


화면1. Zone 멤버십을 사용하는 표준 코드 그룹들

무쟈게 햇갈릴 것이다. 구체적인 예를 드는 것이 이해를 도우리라 판단한 필자, 예제 서비스 들어 간다. My_Computer_Zone 이라는 코드 그룹은 Zone 멤버십을 사용하고 Zone 멤버십 중 조건으로 My Computer 영역을 사용하고 있다. .NET Framework Configuration MMC에서 My_Computer_Zone의 속성을 살펴보면 멤버십으로서 Zone 멤버십을 사용하고 있으며 그 조건으로서 My Computer 영역을 사용하고 있음을 알 수 있다. 다시 말해서, My Computer 영역에서 로드 한 어셈블리는 My_Computer_Zone 이라는 코드 그룹에 포함되는 것이다. 조금 더 쉽게 말해, 로컬 컴퓨터의 디스크(하드 디스크건, 이동식 디스크이건)에서 로드 한 어셈블리는 My_Computer_Zone 코드 그룹에 포함되는 것이다. 이제 이해가 되는가? 그래도 이해가 안 간다면 화면2를 살펴보기 바란다. 그래도 이해가 안 가면... 조상을 탓하길... -_-;


화면2. My_Computer_Zone의 멤버십 조건 속성. Zone 멤버십을 사용하며 조건으로 My Computer 영역이 사용되었다.

비슷하게 LocalIntranet_Zone 코드 그룹은 Local Intranet 영역에서 로드 한 어셈블리들을 묶는 코드 그룹이며, Internet_Zone 코드 그룹 역시 Internet 영역에서 로드 한 어셈블리들을 묶는 코드 그룹이다. 다른 코드 그룹도 마찬가지 이다.

여기서 퀴즈... 어셈블리를 공유 폴더인 \\fileserver\share 폴더에서 로드 했다면, 이 어셈블리는 어떤 코드 그룹에 속할까? 당연히 fileserver 는 로컬 인트라넷 영역에서 로드 했으므로 LocalIntranet_Zone 코드 그룹에 속하게 된다. http://www.simpleisbest.net 에서 다운로드 받은 어셈블리는 어떨까? 기본적으로 www.simpleisbest.net 은 Internet 영역이므로 Internet_Zone 코드 그룹에 속하겠지만, 이 사이트를 IE에서 Trusted Sites에 등록하거나 Local Intranet 에 등록하면 코드 그룹은 바뀔 수 있음에 유의하자.

Site 멤버십은 코드를 로드 한 사이트를 조건으로 하는 멤버십이다. 예를 들어 새로운 코드 그룹을 만들 때 Site 멤버십을 사용하고 사이트 조건으로 localhost를 설정하면, localhost 사이트에서 로드 한 (파일 공유를 통해서건, http, ftp를 통해서건 관계 없다) 어셈블리는 모두 이 코드 그룹에 포함되게 된다. 화면1 에서 마지막 두 코드 그룹(SmartClient 어쩌고 해 놓은 코드 그룹)은 사이트 멤버십을 사용해서 필자가 정의한 코드 그룹이다. 각 코드 그룹은 localhost 사이트와 workman (컴퓨터 이름이다) 사이트에서 로드 되는 코드에 대한 코드 그룹을 정의하고 있다.

코드 그룹을 생성하기 위해서는 화면1과 같은 .NET Framework Configuration MMC 화면에서 All_Code 코드 그룹을 오른쪽 클릭하여 새로운 코드 그룹을 지정하면 된다. 코드 그룹의 이름과 설명(description)을 입력하고 나면 화면3과 같이 멤버십과 조건을 입력하는 대화 상자가 나타나는데, 이 때 Site 멤버십을 선택하고 사이트 이름(컴퓨터 이름)을 입력하면 된다. 이 때 사이트 이름은 단순한 컴퓨터 이름이나 DNS 이름 혹은 IP를 입력해도 된다. 주의할 점은 컴퓨터 이름과 IP가 같은 컴퓨터를 나타내고 있더라도 둘은 서로 구분된다는 점이다.


화면3. Site 멤버십을 이용한 새로운 코드 그룹 생성

URL 멤버십은 사이트 멤버십과 비슷하다. 다만 조건으로서 사이트의 이름이 아닌 URL을 사용한다. URL로서 설정될 수 있는 값은 http, ftp 등의 일반적인 인터넷 URL 뿐만 아니라 로컬 경로 역시 지정이 가능하다. file://D:\Temp 와 같은 URL은 로컬 디스크의 D 드라이브의 Temp 디렉터리를 의미한다. URL 멤버십의 조건은 항상 맨 마지막에 * (asterisk) 와일드 카드를 표시하여 해당 URL 및 하위 URL에서 로드 되는 모든 코드를 포함하도록 지정한다. 예를 들어 http://www.simpleisbest.net/Apps/* 라는 URL을 사용하면 http://www.simpleisbest.net/Apps 디렉터리 및 그 하위 디렉터리에서 로드 되는 모든 코드는 코드 그룹으로서 정의되는 것이다.

지금까지 살펴본 코드 그룹 이외에도 Strong Name 코드 그룹(Strong Name의 public key token을 조건으로 사용), Publisher 코드 그룹(코드에 서명된 인증서의 조직명, 발행자, 해시값을 조건으로 사용) 등이 있지만 더 이상 설명하진 않겠다.

Evidence

앞서 코드 그룹과 멤버십 조건을 설명할 때, 단순히 어셈블리가 ~ 에서 로드 되면 어떤 코드 그룹에 포함된다고 했었다. 실제로는 이것 보다 약간 복잡한 과정을 거친다. 닷넷 런타임이 어셈블리를 로드 하면 런타임 로더(loader)는 어셈블리에 대한 다양한 정보를 수집한다. 예를 들어, 어셈블리의 Strong Name, 어셈블리에 서명된 인증서(만약 존재한다면), 어셈블리를 로드 한 Site, 어셈블리를 로드 한 Url 등등이 그것이다(상세한 내용은 MSDN 한글판 링크영문판 링크를 참조하기 바란다. 이런 링크 찾는 것도 상당히 수고스럽다. 쥔장의 정성이 괴씸해서라도 한번쯤 클릭해 보는 센스를 갖기 바란다.). 이러한 정보를 어셈블리의 증명(Evidence)이라고 한다. 어셈블리 증명 정보는 로드 시에 수집되며, CAS에서 어셈블리가 어떤 코드 그룹에 속하는지 결정하기 위해 사용된다.

대개의 경우, 어셈블리의 증명은 어셈블리가 로드 될 때 닷넷 런타임 로더에 의해 수집되지만, 어플리케이션 도메인(Application Domain)을 생성하고 도메인에 최초의 어셈블리를 로드 하는 닷넷 CLR 호스트(IE, ASP.NET 작업 프로세스 등)에 의해 주어지기도 한다. 닷넷 CLR 호스트 API와 AppDomain 클래스는 이에 관련된 메쏘드와 매개변수를 가지고 있다. 어찌 되었건 어셈블리가 로드 될 때 수집되거나 CLR 호스트에 의해 주어지는 증명 정보는 코드, 즉 어셈블리가 어떤 코드 그룹에 포함되는지를 결정하는데 멤버십 조건에 대응되는 중요한 정보이다. 이런 것이 있다는 것을 알아두면 피가 되고 살이 된다.

Permission & Permission Set

코드(어셈블리)가 어떤 코드 그룹에 속해있는가가 결정되면, 이제 그 코드 그룹이 어떤 권한(Permission)을 갖는가를 정의해야 할 것이다. 닷넷 CAS에서 정의하는 권한은 매우 다양하며 커스텀 권한을 정의할 수도 있다. 가장 기본적인 코드 수행 권한이 있는가 하면, 파일 I/O에 대한 권한, 레지스트리 액세스 권한, 소켓 액세스 권한, 웹 액세스(HttpWebRequest) 권한 등등이 존재한다. 이들 권한은 단순히 권한이 있고 없음만을 나타내기도 하지만, 특정 영역에 대한 액세스 권한이 있는지 없는지를 나타내기도 한다. 예를 들어, 코드 수행 권한은 단순히 어셈블리의 코드를 수행할 권한이 있는지 없는지 만을 나타내지만 파일 I/O 권한은 특정 폴더 및 하위 폴더에 대해 읽기, 쓰기, 추가(append) 권한이 있는지를 나타낼 수도 있다. 또한 소켓 이나 웹 액세스 권한은 특정 IP 혹은 사이트에 대해서만 액세스가 가능하도록 설정할 수 있다. 물론, 파일 IO 권한이나 소켓/웹 액세스 권한에 무제한의 권한인 제약 없음(unrestricted)을 줄 수도 있다.

코드 그룹에 각각 CAS의 권한을 부여 한다면 상당히 다양한 조합이 나올 수 있을 것이다. 예를 들어 내가 어떤 코드 그룹을 만들었고 이 코드 그룹에 권한을 주기 위해서는 매우 다양한 권한을 이 코드 그룹에 주어야 할 것이다. 이러한 불합리(?)를 없애기 위해 CAS에서는 권한 집합(Permission Set)이란 개념을 사용한다. 권한 집합은 일련의 권한들에 대한 집합으로서 코드 그룹에 권한을 줄 때 각기 권한을 주는 것이 아니라 권한 집합 단위로 권한을 주는 것이다. 일례로, 특정 사이트에서 다운로드 받은 어셈블리에 권한을 부여하기 위해서는 권한 집합을 만들고 필요한 권한들을 권한 집합에 포함시키는 것이다. 그리고 이 권한 집합을 코드 그룹의 권한으로서 할당한다는 것이다. 약간 복잡하다고 생각할 수 있지만 다양한 코드 그룹을 보다 일목요연하게 관리하는 기법이 되겠다.

닷넷 프레임워크에서 표준적으로 정의하는 권한 집합은 Internet, LocalIntranet, Everything, Nothing, Execution, FullTrust 등이 있다(화면4 참조). 눈치 챌 수 있겠지만 Internet_Zone 코드 그룹에 할당된 코드 그룹은 Internet 권한 집합이며, LocalIntranet_Zone 코드 그룹에 할당된 코드 그룹은 LocalIntranet 권한 집합이다. 각 권한 집합이 포함하는 권한들을 확인하는 가장 좋은 방법은 .NET Framework Configuration MMC 화면에서 권한 집합의 내용을 직접 살펴보는 것이다. Internet 권한 집합의 경우, 몇몇 권한들이 허용되어 있을 뿐이다.

다른 권한 집합들은 다 쉽게 이해할 수 있을 것이지만 Everything 권한 집합과 FullTrust 권한 집합에 대해서는 약간 더 설명하도록 하겠다. Everything 권한 집합은 닷넷 프레임워크에서 제공하는 기본 권한들을 모두 포함하는 권한 집합이다. 따라서 닷넷이 기본으로 제공하는 권한들이 어떤 것이 있는가 살펴보기 위해 Everything 권한 집합을 살펴보는 것도 좋다. Everything 권한 집합에서 주의할 점은 이 권한 집합이 모든 권한을 주고 있지 않다는 점이다. 비록 모든 권한들을 포함하고 있지만 각 권한이 모두 무제한의 권한을 허용하지 않는다. 그래서 FullTrust 라는 권한 집합이 존재한다. FullTrust 권한 집합은 특수한 권한 집합으로서 권한들에 대한 집합이 아니다. 어떤 CAS 권한 검사도 통과할 수 있는 특수한 권한 집합인 것이다. 또한 일부 CAS 권한 확인 코드는 하드 코딩에 의해 코드가 특정 권한이 있는지 검사하기 보다는 권한이 FullTrust 인지 아닌지를 검사하는 경우도 있다. 이 때문에 특정 코드 그룹에 모든 권한을 주고 싶을 때는 Everything 보다는 FullTrust 권한 집합을 주어야 한다. 사실 Everything 권한 집합은 그다지 많이 사용되지 않으며, FullTrust를 더 선호하는 이유도 이러한 이유 때문이다.


화면4. 권한 집합의 종류와 Everything 권한집합의 권한들

Break Time

잠시 정리의 시간을 가져보자. CAS는 누가 어떤 자원을 액세스하는 가에 추가하여 어떤 코드에 의해 해당 작업이 수행되는가를 추가적으로 검사한다. 이를 위해 코드를 코드 그룹으로 분류하며, 코드는 각 코드 그룹이 명세 하는 멤버십 조건에 의해 코드 그룹들에 포함되게 된다. 그리고 각 코드 그룹은 권한 집합에 의해 명세 된 권한을 갖게 되는 것이다. 잘 이해가 안 가는가? 다시 한번 MSDN 자료와 이 글을 읽어 보기 바란다. 그래도 이해가 안 간다면... 필자도 어쩔 수 없다. 필자의 글이 너무 난해하거나 독자의 이해력 혹은 짱구 탓이니... 필자는 더 이상 자세하고 쉽게 쓸 시간적 여유도 정력도 그리고 의지도 없으니 독자들이 알아서 하길... 텨~텨~텨~ -_-;

Policy Level Hierarchy & Code Group Hierarchy

지금까지 보여준 몇몇 스크린 샷을 보면 특이한 점을 발견했을 것이다. 발견 못했다면 말고... -_-; 화면1을 보면 코드 그룹이 마치 트리 처럼 표현 되어 있다. 맨 위에 All_Code 라는 코드 그룹이 있고 그 하위에 Internet_Zone 등등의 코드 그룹이 있었다. 그리고 몇몇 코드 그룹은 하위에 무언가가 있을 듯한 + 표시도 보았을 것이다.

그렇다. 코드 그룹은 계층 구조를 가지고 있으며 코드 그룹은 하위 코드 그룹을 가질 수 있다. 부모 코드 그룹에 속한 코드(어셈블리)는 그 하위 코드 그룹에 포함될 수 있다. 하지만 부모 코드 그룹에 속하지 않는 코드는 하위 코드 그룹에 포함될 수는 없다.

All_Code 코드 그룹의 멤버십 조건은 All Code 라는 멤버십을 사용하여 이 멤버십은 모드 코드를 포함하는 멤버십이다. 따라서 모든 코드는 All_Code 코드 그룹에 포함되게 되며 그 하위에 존재하는 My_Computer_Zone, Internet_Zone 등의 하위 코드 그룹에도 포함될 수 있는 것이다.

그렇다면 화면1화면4에서 보이는 Enterprise, Machine, User 등은 무엇인가? 이는 소위 정책 레벨(Policy Level)이라는 것으로서 CAS의 코드 그룹과 권한 집합을 정의하는 정책의 수준이 Enterprise 수준, Machine 수준, 사용자 수준으로 존재한다는 것이다. 이름만 봐도 추측할 수 있듯이, Enterprise 수준은 기업 혹은 회사 수준에서 적용하는 CAS 정책(코드 그룹 및 권한집합)이며, Machine 수준은 해당 컴퓨터에 적용하는 CAS 정책이고, User 수준은 각 사용자 별로 적용되는 CAS 정책을 말한다. Enterprise 수준과 Machine 수준은 Administrator 만이 변경할 수 있지만 User 수준은 각 사용자가 바꿀 수 있다. 대개의 경우, Enterprise 수준은 기업 수준에서 정의된 CAS 정책을 배포에 의해 설정한다. CAS가 아직 Active Directory와 연계되지 않기 때문에 Enterprise 정책을 자동으로 배포해주는 기능은 없다. 언젠가는 Enterprise 정책이 Windows 보안 정책처럼 Active Directory에 의해 자동으로 배포되고 전파되는 기능이 추가될 것이다. 하지만 그 때까지는 Enterprise 정책은 사용되지 않을 것으로 보인다. Enterprise 정책은 이를 증명(?)하듯이 달랑 All_Code 코드 그룹 하나만을 갖고 있다. Machine 정책 수준은 컴퓨터 수준에서 적용되는 보안 정책이다. 사용자에 상관없이 이 컴퓨터에서 수행되는 모든 닷넷 코드는 Machine 정책의 영향을 받게 된다.. User 정책은 하나의 컴퓨터에 각 사용자 별로 다양한 CAS 정책을 설정할 수 있도록 해준다. 닷넷 런타임은 Enterprise, Machine, User 정책 수준 순서로 어셈블리가 어떤 코드 그룹에 속하는지를 검사한다. 나중에 자세히 설명하겠지만 각 정책 수준에서 정의하는 어셈블리의 권한은 교집합 연산을 수행한다.

Calculation of Permission

이미 눈치 챘을 것이지만, 어셈블리는 여러 코드 그룹에 포함될 수 있다. 하나의 Enterprise, Machine, User 정책 수준들 중 하나의 정책 수준 내에서도 여러 코드 그룹에 포함될 수 있지만, 정책 수준들 사이에서도 여러 코드 그룹에 포함될 수 있는 것이다. 그렇다면 어셈블리가 포함되는 여러 코드 그룹들에게 할당된 권한은 어떻게 최종 코드의 권한으로서 결정되는 것일까? 이제부터 그것에 대한 설명을 하고자 한다. MSDN의 다음 링크는 코드 그룹이 결정되고 권한이 주어지는 방법에 대해 설명하고 있다.

일단 런타임은 각 정책 수준(policy level) 별로 어셈블리가 어떤 코드 그룹에 포함되는지 찾는다. 코드 그룹은 계층 구조이기 때문에 최 상위 코드 그룹부터 하위 코드 그룹들에 대해 코드 그룹의 멤버십 조건과 어셈블리의 증명 정보(evidence)를 비교하는 방식으로 포함되는 코드 그룹들 찾게 된다. 구체적으로 예를 들어 보자. 화면1과 같은 Machine 정책이 있을 때, http://workman/SmartClientBasic 에서 ClientModule.dll 을 로드 했다고 가정해 보자. 이 어셈블리의 증명 정보 중 Site는 workman 이 될 것이며 Url은 http://workman/SmartClientBasic/ClientModule.dll 이 될 것이다. 최상위 코드 그룹이 All_Code 이고 이 코드 그룹의 멤버십 조건은 All Code 이다. 따라서 ClientModule.dll 어셈블리는 All_Code 코드 그룹에 포함되게 되고 그 하위 코드 그룹들도 포함 여부를 판단하게 될 것이다. 코드 그룹의 멤버십 조건들을 판단하면 workman 이란 사이트는 로컬 인트라넷 영역이므로 LocalIntranet_Zone 코드 그룹에도 포함된다. 그리고 그 하위 코드 그룹인 Intranet_Same_Site_Access 및 Intranet_Same_Directory_Access 코드 그룹에도 포함된다(화면1에는 나타나 있지 않다. 직접 확인하기 바란다). 이 두 코드 그룹은 커스텀 코드 그룹으로서 다운로드 받은 사이트/디렉터리에 대해 액세스 권한을 주기 위한 코드 그룹이다. 그리고 마지막으로 SmartClient - workman 이라는 코드 그룹에도 포함된다. 이 코드 그룹은 필자가 Site 멤버십 조건을 이용하여 Site 증명 정보가 workman 이 되도록 만들어 놓은 코드 그룹이다. 결과적으로 http://workman/SmartClient 에서 로드 한 ClientModule.dll 어셈블리는 All_Code, LocalIntranet_Zone, Intranet_Same_Site_Access, Intranet_Same_Directory_Access, SmartClient - workman 코드 그룹에 포함되게 되는 것이다.

어셈블리가 어떤 코드 그룹에 포함되는지 눈으로 확인할 방법이 없을까? 물론 있다. .NET Framework Configuration MMC에서 왼쪽 트리에서 런타임 보안 정책(Runtime Security Policy) 노드를 선택하고 오른쪽 클릭을 하면 나타나는 컨텍스트 메뉴에서 어셈블리 확인(Evaluate an Assembly) 메뉴를 선택하면 화면5와 같은 어셈블리의 CAS 권한을 살펴볼 수 있는 대화 상자가 나타난다. 여기에서 어셈블리의 경로(URL 혹은 로컬 파일 경로)를 입력하고 코드 그룹을 보는 옵션을 선택하면 된다. 결과로서 화면6과 같이 각 정책 수준별로 어셈블리가 포함되는 코드 그룹들의 목록을 알 수 있다.


화면5. 어셈블리 CAS 권한 확인


화면6. 어셈블리가 포함되는 코드 그룹 결과

정책 수준 내에서 어셈블리가 포함되는 코드 그룹들이 결정되면, 런타임은 각 코드 그룹이 허용하는 권한 집합의 권한들을 "합집합" 연산을 수행하여 권한을 계산하게 된다. 동일 정책 수준 내에서 권한들은 합집합 연산이라는 점이 중요한 점이 되겠다. Machine 정책 수준의 All_Code 코드 그룹의 권한 집합이 왜 Nothing 으로 설정되어 있는가(확인해 봐라 쫌...)에 대한 답이 되겠다. All_Code 코드 그룹이 비록 Nothing 이지만 동일 정책 수준 내에서 권한들이 합집합 되므로 LocalIntranet 코드 그룹의 권한 등이 계속 추가될 것이므로 문제가 없다. 만약 All_Code 코드 그룹이 FullTrust 라면 하위 코드 그룹의 권한 집합은 아무런 의미가 없어져 버린다. 우리의 예에서 SmartClient - workman 코드 그룹의 권한 집합을 필자가 FullTrust로 설정해 놓았으므로 결과적으로 ClientModule.dll 어셈블리는 적어도 Machine 정책 수준에서 FullTrust, 즉 제약이 없는 CAS 권한을 갖게 된다.

같은 방식으로 Enterprise, User 정책 수준 역시 코드 그룹을 결정하고 각 코드 그룹에 주어진 권한 집합이 합집합으로 연산된다. 정책 수준이 검사되는 순서는 Enterprise, Machine, User 순서임에 유의하도록 하자. 각 정책 수준 별로 합집합 연산된 권한들이 나오면 각 정책 수준별 권한들에 대해서 교집합 연산이 수행된다. 다시 말해, Enterprise, Machine, User 의 각 정책 수준이 모두 허용하는 권한들 만이 최종 어셈블리가 갖는 CAS 권한이 된다는 얘기 이다. 정책 수준 별로 결정된 권한 집합들끼리는 교집합 연산이 수행된다는 점에 유의하도록 하자. 화면6을 참고로 해서 권한을 계산해 보자. 먼저, Enterprise 및 User 정책의 All_Code 그룹은 FullTrust 이므로 교집합 연산에 영향을 주지 못한다(중/고등학교 때 배웠던 집합 연산이다. 언제 써먹나 고민하지 말고 잘 기억해 봐라...). Machine 정책의 코드 그룹에 의해 결정된 권한만이 최종 권한으로 결정되는 것이다.

앞서 화면5에서 보였던 대화상자를 통해 연산된 권한 역시 알아 볼 수 있다. 코드 그룹을 보는 옵션 대신 권한을 보는 옵션을 선택하면 화면7과 같이 연산된 권한을 알아 낼 수도 있다. 멋지지 않은가? 아님 말고...


화면7. 연산된 권한 결과

화면7과 같은 결과는 CAS 정책에 의해 어셈블리에 허용된 권한이다. 닷넷 런타임은 허용된 권한 외에도 최종적으로 한가지 더 확인작업을 수행한다(C8... 쥐랄 같이 복잡하다 -_-;). 이 작업은 거의 사용되지 않으므로 몰라도 상관 없는 내용이긴 하지만, MSDN에 나오므로 설명하도록 하겠다.

각 어셈블리는 자신이 필요한 혹은 요구하거나 거부하는 CAS 권한을 명시할 수 있다. 어셈블리 수준의 특성(attribute)을 통해 어셈블리가 요구하는 최소 권한을 명시함으로써, 허용된 권한(앞서 졸라게 설명했다)이 요구하는 권한을 포함하고 있지 않으면 PolicyException을 발생하도록 할 수 있다. 다음은 어셈블리가 파일 IO 권한을 제한 없이 사용할 것을 요구하고 있다. 만약 허용된 권한에 파일 IO 권한이 Unrestriced 가 아니라면 PolicyException 이 발생한다.

[assembly: FileIOPermission(RequestMimimum, Unrestricted=true)]

이외에도 거부한 권한(RequestRefuse)을 명시할 수도 있는데, 허용된 권한이 이 거부한 권한을 포함하는 경우 최종적으로 어셈블리가 갖는 권한에는 제외시킬 수도 있다. 예를 들어 허용된 권한이 FullTrust 였고, RequestRefuse로 FileIOPermission 을 주었다면 어셈블리가 갖는 실제 최종 권한은 FileIOPermission을 제외한 모든 권한이 되게 된다. 상세한 내용은 MSDN의 문서를 참고하기 바란다.

How to Check CAS Permission ?

지금까지 CAS 정책에 의해 권한이 어떤 코드에 어떻게 주어지는지를 살펴보았다. 닷넷 런타임은 지금까지 설명한 CAS 정책에 의해 로드 되는 어셈블리에게 CAS 권한을 부여하게 된다. 그렇다면... 실제로 이렇게 주어진 권한을 어떻게 사용할까? 아니, 어셈블리가 주어진 권한을 갖고 있는지 없는지를 어떻게 판단해야 할까?

Checking Permission Programmatically

앞서 간략히 CAS에서 정의하는 권한에 대해 설명하였다. 파일 IO 권한, 레지스트리 액세스 권한 등등이 이에 해당하는 권한이다. 이들 권한은 각기 권한에 해당하는 권한 클래스를 갖는다. 파일 IO 권한은 FileIOPermission 클래스가 그것이며, 레지스트리 액세스 권한은 RegistryPermission 클래스가 바로 그것이다. 이들 클래스들은 모두 추상 클래스(abstract class)인 CodeAccessPermission 클래스에서 파생된 것들인데, 이들 권한 클래스가 권한을 정의하고 검사하는 클래스이다. 앞서 파일 I/O 권한을 정의할 때, 파일 액세스에 대한 무제한의 권한을 주거나 특정 폴더에 대해 읽기 혹은 쓰기 권한을 줄 수 있다고 했다. 이렇게 파일 I/O 권한을 정의 행위는 FileIOPermission 클래스의 인스턴스를 생성하고, 주어진 폴더에 읽기 혹은 쓰기 권한을 설정하는 것과 같다. 다음 코드는 C:\\Temp 디렉터리에 대한 파일 I/O 권한으로 읽기 권한을 정의하는 것이다.

FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Read, "C:\\Temp");

이렇게 정의된 권한을 코드가 갖고 있는지 파악하는 방법은 대단히 간단하다. 이 인스턴스에 대해 Demand() 메쏘드를 호출하면 된다.

permission.Demand();

Demand() 메쏘드가 호출되면, 현재 Demand() 메쏘드를 호출한 코드를 포함하는 어셈블리는 물론이요, 호출 스택을 거슬러 올라가면서 발견되는 모든 어셈블리들에 대해 C:\Temp 폴더에 대해 읽기 권한이 있는지 검사를 수행한다. 이것이 중요한 점이 되겠다. CAS 보안의 특징은 단순히 현재 수행되는 코드(어셈블리) 뿐만 아니라 호출 스택을 거슬러 올라가면서 나타나는 각각의 코드들에 대한 권한 검사를 모두 수행한다는 점이다. WIN32 보안 모델이 어떤 행위를 수행하는 사용자를 검사한다는 점에서 볼 때, CAS가 어떤 행위를 수행하는 현재 코드 뿐만 아니라 그 코드를 호출한 상위 코드들 모두를 검사한다는 것이 커다란 특징이자 장점으로 볼 수 있는 것이다.

잘 이해가 안 가는가? 보다 구체적으로 예를 들어 보겠다. FileIOPermission 클래스를 이용하여 파일 I/O 액세스 검사를 수행하는 대표적인 클래스는 FileStream 클래스이다. 이 클래스는 생성자 수준에서 주어진 파일에 대해 읽기/쓰기 권한이 있는가를 검사하기 위해 FileStream 생성자에게 넘겨진 매개변수(파일 경로, 읽기/쓰기 모드 등)를 기반으로 FileIOPermission 인스턴스를 생성한다. 그리고 이 인스턴스에 대해 Demand() 메쏘드를 호출하도록 되어 있다. 그렇다면 잘 생각해 보자. FileStream 클래스는 mscorlib.dll 에 정의되어 있다. 그리고 이 어셈블리는 로컬 디스크(특히 GAC)상에서 로드 된다. 그렇다면 로컬 디스크에서 로드 된 어셈블리는 My_Computer_Zone 코드 그룹에 포함되므로 FullTrust 아닌가? 사실 FileStream 클래스에서 수행하는 CAS 권한 검사는 이 클래스를 호출하는 호출자(caller)가 권한이 있는지를 검사하는 것이다. 하지만 그것이 간단하지 않다. File 클래스의 Open 메쏘드는 내부적으로 FileStream 클래스를 호출한다. 이 경우, FileStream의 호출자 역시 mscorlib.dll 어셈블리 내에 있는 File 클래스가 되어 버리므로 File 클래스를 호출하는 호출자의 권한을 살펴보아야 하는 것이다. 이런 식으로 따지자면 호출 트리 상에 나타나는 모든 코드를 살펴봐야 한다는 얘기가 된다.

그렇다. 닷넷 런타임은 호출 스택을 거슬러 올라가면서 나타나는 각 어셈블리에게 주어진 권한(어셈블리에게 주어진 권한은 앞서 정책을 통해 주어진다고 이미 설명했다)을 검사하도록 되어 있다. 이렇게 함으로써 인터넷에서 다운로드 받은 어셈블리와 같이 신뢰되지 않은 어셈블리가 신뢰된 어셈블리를 호출하여 간접적으로 권한이 상승되는 상황을 방지할 수 있다. 이와 같은 상황을 보여주는 것이 그림1 이다.


그림1. 어셈블리 별 CAS 권한 및 호출 스택에 의한 권한 검사.

그림1의 상황은 Laucher.exe를 http://www.simpleisbest.net/Apps 에서 다운로드 하여 코드가 수행되었고 Main() 메쏘드는 다시 ClientModule.dll 을 LoadFrom 메쏘드를 사용하여 http://workman/SmartClient 디렉터리에서 로드 하였다. Main 메쏘드는 ClientModule.dll 어셈블리에 존재하는 foo() 메쏘드를 호출하였고 foo() 메쏘드는 FileStream 클래스를 이용하여 C:\Temp\data.txt 을 열고자 시도한다. 이러한 상황에서 Launcher.exe, ClientModule.dll, mscorlib.dll 어셈블리는 각기 서로 다른 권한을 부여 받게 된다. 앞서 설명한대로 어셈블리의 증명 정보(evidence)에 의해 코드 그룹이 결정되고 코드 그룹에 부여된 권한이 설정되는 것이다. 화면1과 같은 정책 상황을 가정할 때 Laucher.exe는 Internet 권한 집합을, ClientModule.dll 은 FullTrust 권한 집합을, 그리고 mscorlib.dll 역시 FullTrust 권한 집합을 갖게 된다(정확히 말해 권한 집합을 갖는다는 말은 어폐가 있다. 권한 집합에 포함된 권한들을 갖는다는 말이 보다 정확하며 실제 여러 코드 그룹에 포함됨에 따라서 권한 집합과는 다른 권한들을 갖을 수도 있다).

FileStream 클래스가 사용됨에 따라 FileStream 클래스는 호출자가 액세스하고자 하는 경로와 읽기 쓰기 모드에 의해 FileIOPermission 클래스의 인스턴스를 생성하고, Demand() 메쏘드를 호출한다. 이는 호출자가 파일 액세스 권한이 있는가를 검사하기 위함이다. Demand() 가 호출되면 닷넷 런타임은 먼저 Demand() 메쏘드를 호출한 코드의 어셈블리가 주어진 FileIOPermission 권한(이 경우, C:\Temp\data.txt 파일에 대한 액세스 권한)이 있는지 검사한다. 권한이 없는 경우 즉시 SecurityException이 발생하는데 mscorlib.dll 은 FullTrust 권한을 가지므로 권한 검사는 호출 스택을 거슬러 올라가며 동일한 권한 검사를 수행하게 된다. ClientModule.dll 역시 FullTrust를 가지므로 권한 검사를 통과하게 된다. 호출 스택의 마지막인 Launcher.exe 어셈블리는 Internet 권한 집합을 갖으므로 로컬 디스크의 파일에 대한 액세스 권한이 없다. 따라서 SecurityException 이 발생하게 된다. 이 예외의 발생위치는 Demand() 메쏘드의 내부가 되겠다.

이렇게까지 구체적인 예를 들어줬으면, 이해해 줘야 한다. 더 이상 상세히 설명할 능력을 필자는 가지고 있지 않다. 이래도 이해가 안 간다면 대략 낭패일 수 밖에 없으며, 다른 자료를 더 찾아보라고 말할 수 밖에 없겠다. 쯔읍...

마지막으로 독자들에게 하나 이야기 하고 싶은 것은 CAS 보안 검사 확인은 Windows 보안 검사 이전에 수행된다는 것이다. FileStream 의 예에서 보였듯이, 실제 파일을 액세스하기 전에 CAS 보안 검사가 수행된다. 그리고 나서 실제 파일 액세스를 수행하게 되는데, 바로 이 실제 파일 액세스 시에 Windows 보안 검사가 수행된다. 따라서 CAS 보안 검사를 먼저 통과해야만 현재 사용자 계정이 해당 자원(파일, 등등)에 대한 읽기, 쓰기 권한이 있는가가 검사된다. 요점에 주의하도록 하자.

Checking Permission Declaratively

앞서 예제처럼 FileIOPermission 같은 권한 클래스를 생성하고 Demand() 메쏘드를 호출함으로써 프로그램적으로 CAS 권한을 확인할 수도 있지만, 특성(attribute)를 이용하여 선언적으로도 권한 확인이 가능하다. 메쏘드 그리고 클래스 수준에 FileIOPermissionAttribute 와 같은 특성 클래스를 이용하여 CAS 권한 확인을 수행할 수 있다는 말이 되겠다. 다음 코드 예제와 같이 메쏘드에 특성을 표시할 수도 있으며 클래스 수준에서도 선언적으로 CAS 권한 확인을 수행할 수 있다.

[FileIOPermission(SecurityAction.Demand, Read="C:\\Temp")]

public static void foo()

{

??? // 내용?생략?...

}

개발의 편의성을 보았을 때 선언적인 권한 확인이 보다 장점이 있을 수 있겠지만, 효율적인 면에서나 유연성 면에서는 코드에 의한 권한 확인이 더 유리하다. 앞서 FileStream의 예에서와 같이 호출자가 파일의 경로를 매개변수로 넘겨 준다면 선언적인 권한 검사 방법으로는 동적인 권한 검사가 불가능하기까지도 하기 때문이다.

CAS In SmartClient World

실제 스마트 클라이언트를 개발하면서 개발자가 직접 CAS 권한 검사를 해야 하는 경우는 발생하지 않을 것이다. 권한 확인 작업은 대부분 닷넷 프레임워크의 클래스 라이브러리 내에서 수행되므로 여러분이 굳이 검사를 수행하지 않아도 된다. 즉, 닷넷이 제공하는 다양한 분야의 엄청나게 많은 클래스들 곳곳에서 FileIOPermission 클래스, RegistryPermission 클래스, SecurityPermission 클래스의 인스턴스를 만들고 Demand() 메쏘드를 호출하는 코드가 들어 있다는 말이 되겠다. 여러분이 스마트 클라이언트 관련 프로그램을 작성하면서 부딪치게 될 CAS 관련 이슈는 스마트 클라이언트 어셈블리를 위해 어떻게 코드 그룹을 작성하고 이 코드 그룹에 어떤 권한을 주어야 하는가가 될 것이며, 이것을 사용자가 아닌 프로그램적으로 설정하는 방법을 연구하는 것이 될 것이다.

사실, 매우 특별한 경우가 아니라면 스마트 클라이언트가 아닌 일반 ASP.NET 응용 프로그램이나 윈도우 응용 프로그램을 작성할 때도 CAS 권한 확인을 고려할 일은 거의 없다. FileIOPermission 이니 RegistryPermission 이니 하는 클래스는 여러분의 코드에 나타날 일이 거의 없는 클래스들이다. 그럼에도 불구하고 이를 소개한 이유는 원리를 이해하는데 도움이 되기에 간략히(?) 설명한 것이다.

이 글에서는 CAS 정책 수준(Policy level), 코드 그룹(code group)에 대해서는 상당히 자세히 살펴보았지만 권한 집합, 권한, 그리고 권한 검사에 대한 부분은 아주 간략히 살펴본 정도이다. 실제로 CAS 에 대해 읽어 보아야 할 MSDN의 자료는 상당히 방대하다. 이 글에서 그러한 많은 내용을 모두 다룰 수 없음은 당연 빤쑤가 되겠다. 다만 스마트 클라이언트에서 CAS 로 인해 발생하는 알 수 없는 SecurityException이 왜 발생하는가를 이해하기 위해 필요한 부분만을 설명했다고 이해해 주기 바란다.

What's Next

이번 포스트는 CAS의 기본에 대해서만 살펴보았다. 다음 포스트에서는 스마트 클라이언트가 CAS 보안에 의해 SecurityException을 발생하지 않도록 보안 정책을 설정하는 기본 요령 및 팁과 이러한 보안 정책을 .NET Framework Configuration MMC를 사용하는 관리적 기법이 아닌 코드에 의해 코드 그룹을 추가하고 권한을 설정하는 방법을 알아보도록 하겠다. 다음 포스트 역시 기약이 없지만... 최대한 노력할 것을 약속하는 바이다. 지겹고 재미없는 글을 읽어준 독자에게 심심한 감사를 드리며... 이만... -_-;



Comments (read-only)
#re: 스마트 클라이언트, 그것을 알려주마 (IV) : CAS Fundamentals / 앤시스 / 2006-04-29 오후 10:25:00
드디어 올라왔군요!! 기다린 보람이 있네요. ^^
즐거운 주말 잘 보내세요!!
#re: 스마트 클라이언트, 그것을 알려주마 (IV) : CAS Fundamentals / wishy / 2006-05-02 오전 9:08:00
드디어 올라왔군요!!2
잘보겠습니다 ^^
#re: 스마트 클라이언트, 그것을 알려주마 (IV) : CAS Fundamentals / 블로그쥔장 / 2006-05-02 오전 11:37:00
늦어서 죄송합니다... -_-;
아무쪼록 도움이 되셨기를 바랍니다...
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 양대홍 / 2006-05-02 오후 3:47:00
이번에도 좋은 자료, 감사합니다. ^^
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / king / 2006-05-03 오후 4:15:00
좋은 글 감솨~!!!

그런데... 몇번은 더 읽어봐야 ..될듯~!

짱구탓?조상탓?을 해야 할까?나 ~ 고민중 (=,.=);;;

난독증 비슷(?제가워낙..주위가 산만해서...한 곳에 길게 집중을 잘 못함돠~)한게 있어서리....참~!

글이 많으면 금세....제 머리속에선...딴 짓을 하고 있죠..그래서 그림 들어간거 좋아합니다....푸허~!

이러면서도 ... 프로그램한다고...합니다...푸히~

모쪼록~~ 쥔장님의 또 다른...좋은 포스트....늦더라도..쭈욱~~~계속되길...

에~~바라마지않(것)습니다.(김대중 전대통령버전~으로.)
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 힘들어 / 2006-11-06 오후 7:33:00
오랜만에 또 질문을 올려보네요^^;; 맨날 질문만해서 죄송해요 ;
2005를 설치하고 다시 테스트를 하고 있습니다 .
이번에는 CAS까지 설정 다 하고 stand-alone은 잘 실행되고 embedded 화면은 여전히 보안에러가 나네요. SQLClient를 사용하는데 이것이 문제네요 ;
stand-alone이 잘 되길래 당연 embedded도 잘 될줄 알았는데 도와주세요..
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 블로그쥔장 / 2006-11-07 오전 10:25:00
인터넷 영역이나 로컬 인트라넷 영역에 대한 기본 CAS 권한은 SQLClient에 대한 권한이 없습니다.
CAS 설정을 다시 한번 확인해 보시라는 것 외엔 특별한 조언을 드리기 힘들군요... -_-;
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 김병익 / 2006-11-14 오후 3:39:00
"Internet_Zone 이라는 코드 그룹은 영역 멤버십Zone membership)에 의해 Internet_Zone 코드 그룹에 포함된다"
와, 이문장 헛갈려요. 주어랑 대상이 동일해서 머리에 쥐나겠어요. Internet_Zone이라는 코드 그룹에 속한 코드들이 그들의 영역멤버쉽이 Internet이라서 Internet_Zone 코드 그룹에 속한다는 뜻인가요? 아 쥐난다.
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 블로그쥔장 / 2006-11-14 오후 4:40:00
Internet_Zone 이란 이름을 가진 코드 그룹은
여러 멤버십 가운데 Zone 이라는 멤버십 규칙에 여러 코드들이 Internet_Zone 코드 그룹에 속하게 된다는 뜻 입니다.
다르게 설명하자면 어떤 코드 A가 있을 때 이 A라는 코드가 Internet_Zone 코드 그룹이 정의하는
Zone 멤버십을 만족하게 되면, 코드 A는 Internet_Zone 코드 그룹의 일부로 간주된다는 말이지요.
쉬운(?) 내용을 너무 어렵게 써서 죄송합니다... -_-;
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 쿠쿠쿠111 / 2006-11-17 오후 2:16:00
Trusted_Zone 도 SQL Client에 대한 권한이 없는거 같네요. 쩝, 저도 CAS 셋팅과 .Net Framework 2.0을 배포해야 될 거 같네요.
헉, JRE1.4도 체크해so야 되는데 ,,, 된장. 고객들이 별말 없을까요? 쥔장님.
쩝, 기능 구현도 버벅되고 있는데, 옆에서 디자인 야그를 씨부리고 가네. T.,T
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 쿠쿠쿠111 / 2006-11-17 오후 2:20:00
헉, 공들고 왔다 갔다 하더니, 야유회 간다네. 자기들끼리,,, 쩝, 나도 땡땡이다 오늘은 된장.
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 쿠쿠쿠111 / 2006-11-23 오전 8:03:00
정책수준(Enterprise, Machine, User)내, 혹은 정책수준간의 권한 계산을 잘 읽었습니다.
음, 확인 질문 하나만,,, 결론적으로 최종 권한은 Machine 수준내의 특정 zone에 Full Trust 하나만 설정되도, 결과적으로 모든 다운받은 어셈블리 코드들이 full trust 권한을 가지게 되는 것이 맞는지요?
맞다면, 그렇게 권한을 주면 안되겠다는 생각이 드는데,,, 쩝.

#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / WIND / 2007-05-25 오전 11:26:00
Web Page의 Javascript ==> SmartClient 함수 호출은 Assembly 의 ComVisible = True
만으로도 가능 한데;
반대의 경우인
SmartClient 함수 ==> Web Page Javascript 는.. 보안 에러가 떠 버리네요;

방식은 taeyo 사이트의 정성태님의 강좌를 보고 따라 했는데.. 권한 셋팅이 문제가 되버리네요;

웹에서 범용적으로 사용할 SmartClient Control 이라.. 권한 셋팅을 강제하기도 애매하고..

다음과 같은 방식 말고, 다른 방법이 없을까요;;; 몇일째 고민하고 자료 찾다가
질문 드립니다.
------------------------------------------------------------------------------------------------------
object _control_cc = null;

public UserControl1()
{
InitializeComponent();
}



private void button1_Click(object sender, EventArgs e)
{

if (_control_cc != null)
{
Type type = _control_cc.GetType();

type.InvokeMember("", BindingFlags.InvokeMethod, null, _control_cc, null);
}

}


public object Control_cc
{
get { return _control_cc; }
set { _control_cc = value; }
}











#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 블로그쥔장 / 2007-05-25 오후 1:01:00
네... 불가 합니다. CAS 보안을 위배하는 작업은 CAS 보안 설정을 해주어야만
가능하기 때문에 원하시는 작업은 FullTrust 권한을 주거나 적절한 Permission이
있어야만 가능한 작업입니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / WIND / 2007-05-25 오후 1:38:00
답변 감사합니다.

그럼,, 혹시

SmartClient 에 Event 를 강제로 발생시키고,

해당 이벤트를 javascript 가 인식할 수 있는 방법이 있는지요;

SmartClient에서 javascript을 호출하는게 아니라;

SmartClinet에서 이벤트만 발생시키고; 해당 이벤트를 javascript으로 인지해서

SmartClient.getvalue() 이런식으로 진행이 가능할런지요;

지금 혹시나 하고, 테스트 중인데;; control 의 이벤트를 javascript가 인지하는것부터

막히네요.

#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 블로그쥔장 / 2007-05-25 오후 1:52:00
스마트 클라이언트에서 발생하는 이벤트는 일반적인 COM 이벤트와 다를 것이 없습니다.
닷넷 클래스에서 COM 이벤트를 발생시키는 예제는 다음 글을 참조하십시요.

http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/cpguide/html/cpconhandlingeventsraisedbycomsource.asp

위 글에서 사용한 방법을 그대로 스마트 클라이언트에서 사용하면 이벤트를 자바스크립트가
받을 수 있습니다.
하지만 이것이 CAS 권한에 위배 되는지는 저도 테스트를 해봐야 할 것 같네요.

도움이 되셨기를...
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / WIND / 2007-05-25 오후 3:50:00
답변 감사드립니다.
SmartClient의 이벤트 발생은 처리 되었는데..

WinForm에서 SmartClient Control 을 등록하여 이벤트는 잘 가져오고 처리 됩니다.

근데; Script 에서 이벤트 감지가 안되네요.. 아예 안되는건지..


제가 알기론..

<script language="javascript" event="컨트롤이벤트명" for="컨트롤명">
alert('되는가');
</script>

이런식으로 하면 되는걸로 아는데;

감감;; 안되네요.. ㅠ_-
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / 강희기 / 2007-08-29 오후 3:02:00
와웅 잘읽었습니다. 역시 명쾌한 해설~ 굿입니다. 이만큼 내용준비하기도 보통일이 아닐텐데... 역시 대단하십니다. 두고두고 참고 하겠습니다.
다음 내용 읽으러 갑니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / jmbae / 2007-09-09 오후 4:35:00
좋은 설명 감사합니다. 쏙쏙 머리에 들어오네요.. 한 2~3번은 정독한다면요.. ㅎ

앞으로도 좋은글 부탁드립니다!!
#re: 스마트 클라이언트, 그것을 알려주마 (VI) : CAS Fundamentals / tommy / 2008-08-11 오전 11:07:00
정말 고생많이 하셨습니다.
노력해서 꼭 제것으로 만들게요. 감사합니다.