SimpleIsBest.NET

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

이번 글은 지난 포스트에 이어지는 CAS 배포에 대한 글입니다. 스마트 클라이언트 시스템을 구축할 때 항상 걸림돌이 되는 것이 클라이언트 마다 수행되어야 하는 CAS 설정이지요. 대개의 경우 스마트 클라이언트는 필요한 CAS 권한이 부족하기 때문에 클라이언트마다 사이트 혹은 URL에 대해 CAS 설정을 해주어야만 합니다. 이러한 CAS 설정 작업을 최종 사용자에게 수작업으로 하도록 한다는 것이 매우 불합리하기 때문에 자동으로 CAS 설정을 해주는 모듈을 만들고 이것이 클라이언트에서 수행되도록 해주는 일련의 CAS 설정 배포 작업이 필요한 겁니다. 이번 포스트는 CAS 설정을 수행하는 코드들을 살펴보고 이것을 어떻게 클라이언트에 배포하고 수행하도록 하는지 살펴보도록 하겠습니다.

필자주) 이 글에 나타나는 MSDN에 대한 링크는 가능한 한글 자료를 링크하려고 애썼습니다만...(한글 자료 찾는 거 졸라 귀찮습니다...) 일부 자료는 아직 한글화 되어 있지 않아 부득이 영문 자료가 링크된 경우도 있으니 양지하시길 바랍니다. 한글 문서가 오히려 이해하는데 더 어렵다고 생각하시는 분은 브라우저 주소창의 URL에서 ko-KR 을 en-US로 바꾸시면 영문 자료에 접근하실 수 있습니다.


시리즈 목차

Smart Client (VII) : CAS Deployment

지난 포스트에서는 CAS(Code Access Security; 다시 말하지만 맥주 이름이 아니다... -_-)의 기본에 대해 살펴보았다. 사실 지난 포스트에서 알아본 내용은 CAS 프로그래밍에 대해서는 거의 다루지 않았다. 즉, CAS 보안을 통해 자원(파일, 네트워크 등등)을 보호하는 코딩 방법보다는 닷넷 프레임워크에 기본으로 설정된 CAS 보안 정책이 어떻게 구성되어 있는지를 주로 살펴보았다는 말이다. 그 이유는 간단하다. 사실 스마트 클라이언트 프로그램을 작성하다 보면 대부분의 경우에서 CAS 보안을 통해 자원을 보호하는 것 보다 기본 CAS 보안을 어기지 않도록 CAS 설정을 잡아주는 일이 빈번하게 발생하기 때문이다.

그래서 이번 포스트는 프로그래밍적으로 CAS 보안 정책을 수정하는 방법과 이것을 스마트 클라이언트 시나리오 상에서 어떻게 배포하는지에 대해서 알아보도록 하겠다. CAS 정책을 관리하는 클래스와 메쏘드는 상당히 많다. 쑛도 모르는 필자가 어찌 이들을 모두 설명하겠는가? CAS 보안 정책에 코드 그룹을 추가하고 권한을 주는 부분만을 중점적으로 살펴보도록 할 터이니 독자들을 그렇게 알고 있으면 좋겠다. 궁금한 게 더 많다고? 고수가 될 가능성이 보이는 아주 좋은 징조다... MSDN을 찾아 보면, 각 클래스와 메쏘드의 구체적인 설명과 예제 코드도 있으니 시도해보기 바란다.

Programmatically CAS Policy Management

수작업이 아닌 코드에 의해 CAS 보안 정책을 바꾸는 작업은 스마트 클라이언트 시나리오에서 매우 중요한 미션이다. 지난 포스트에서 이미 살펴 보았지만, 코드 그룹을 추가하고 권한을 주는 작업은 아주 간단한 작업이 아닐 뿐더러 설정을 잘못하면 스마트 클라이언트 자체가 구동되지 않는 현상을 초래할 수도 있다. 최종 사용자에게 이러한 CAS 설정을 하도록 한다면 모르긴 몰라도 그 개발자 혹은 아키텍트는 아마 배터지게 욕을 쳐먹거나 심한 경우 쫓겨날 각오를 해야 할지도 모른다. 설령 그렇게 한다 할지라도, 설정에 관여된 문의 전화를 매일 수십 통씩 받아야 할 것이다. 이보다 더 간단한 설정조차 스스로 할 줄 모르는 사용자는 부지기수이다.

따라서, 프로그램적으로 이러한 CAS 보안 정책을 추가/수정하고 이 코드를 클라이언트에 배포하고 수행하도록 하는 것이 정신/육체 건강에 매우 도움이 될 것임을 확신한다. 그래서 프로그램 코드에 의해 CAS 보안 정책을 수정하는 방법은 존재하는가? 친절한 닷넷씨를 무시하지 마라. .NET Framework Configuration MMC에서 수행하는 거의 모든 작업은 관련 클래스와 메쏘드를 모두 가지고 있다. 오늘 집중적으로 살펴볼 부분은 System.Security 네임스페이스와 System.Security.Policy 네임스페이스에 존재하는 일련의 클래스들 이다.

Listing Code Groups

System.Security 네임스페이스와 System.Security.Policy 네임스페이스는 CAS 보안 정책을 다루는 다양한 클래스를 포함하고 있다. 프로그램적으로 CAS 보안 정책을 변경하고 싶다면 바로 이들 네임스페이스의 클래스들을 사용해야만 하는 것이다. 그 중 CAS 정책을 관리하기 위해 시작점이자 종료점이 되는 클래스가 SecurityManager 클래스 이다. 이 클래스에는 CAS 보안이 활성화 되어 있는지를 검사하는 SecurityEnabled 속성부터 CAS에서 가장 기본이 되는 권한인 코드 수행 권한(Execution Rights)이 있는지를 검사하는 CheckExecutionRight 속성이 포함되어 있으며, 특정 권한(Permission)이 현재 코드 및 호출 스택상의 상위 코드들(어셈블리들)에 존재하는지를 검사하는 IsGranted 메쏘드, 주어진 어셈블리의 증명 정보(evidence)를 이용하여 CAS 정책을 적용한 결과 권한 집합을 구하는 ResolovePolicy 메쏘드, XML 형태의 CAS 정책 파일을 로드 하는 LoadPolicyLevelFromFile, 변경된 CAS 정책을 저장하는 SavePolicy 메쏘드, CAS 정책 수준(Policy Level)들을 반환하는 PolicyHierarchy 메쏘드 등을 가지고 있다.

다른 메쏘드들은 MSDN 라이브러리에서 그 용도를 추측하거나 예제 코드를 통해 충분히 이해를 높일 수 있다. 여기서는 SecurityManager 클래스를 통해 CAS 정책 수준들(Enterprise, Machine, User 수준)을 읽고 그 중 Machine 정책 수준을 알아내는 예제 코드를 보인다.

// Policy 레벨 열거를 얻는다.

IEnumerator enumerator = SecurityManager.PolicyHierarchy();

// Policy 레벨들(Enterprise, Machine, User) 중에서 Machine Policy를 찾는다.

PolicyLevel machineLevel = null;

while (enumerator.MoveNext()) {

    PolicyLevel level = (PolicyLevel)enumerator.Current;

    if (level.Label == "Machine") {

        machineLevel = level;

    }

}

if (machineLevel == null)

    throw new InvalidOperationException("Machine Policy를 찾을 수 없습니다.");

리스트1. Machine 정책 수준을 찾는 예제 코드

리스트1은 CAS 보안 정책 수준에서 Machine 정책 수준을 찾는 코드이다. 먼저 SecurityManager 클래스의 PolicyHierarchy 메쏘드를 호출하여 정책 수준들에 대한 IEnumerator 인터페이스를 얻는다. 달랑 IEnumerator 만을 반환하는 것이 이상하지만 이 인터페이스를 통해 각 정책 수준을 나타내는 PolicyLevel 클래스들을 알아 낼 수 있다. PolicyLevel 클래스는 CAS 정책 수준을 나타내는 클래스로서 각 CAS 정책 수준에 포함되어 있는 코드 그룹(Code Group)권한 집합(Permission Set) 등에 대한 정보를 알아 낼 수 있다.

정책 수준을 나타내는 PolicyLevel 클래스를 얻었으니, 이제 코드 그룹에 액세스할 수 있다. PolicyLevel 클래스의 RootCodeGroup 속성은 정책 수준의 최상위 코드 그룹(All_Code 란 이름을 가진 코드 그룹이다)을 반환한다. 이 속성이 반환하는 타입은 CodeGroup 클래스 타입을 반환하는데, CAS 정책의 코드 그룹을 나타내는 클래스라는 점은 찍어도 맞출 수 있을 것이다. CodeGroup 클래스는 abstract 클래스로서 FileCodeGroup, NetCodeGroup, UnionCodeGroup 등의 실제 클래스들에 대한 베이스 클래스이다. 실제 클래스가 어떤 클래스이건 CodeGroup에서 파생되었으므로 CodeGroup 클래스를 통해 액세스하는 것이 불필요한 캐스팅을 피하고 InvalidCastException을 피하는 지름길이다.

코드 그룹은 지난 포스트에서 설명했다시피 계층 구조를 갖는다. 코드 그룹은 하위 코드 그룹을 가질 수 있는 것이다. CodeGroup 클래스 역시 하위 코드 그룹을 나타내기 위해 Children 속성을 갖는다. 이 속성은 하위 코드 그룹을 열거하기 위해 IList 인터페이스를 반환한다. CodeGroup 클래스와 Children 속성을 이용하여 재귀 호출 방식으로 코드를 작성하면 주어진 정책 수준의 코드 그룹들을 나열할 수 있다.

// Root code group을 구한다.

CodeGroup rootCodeGroup = machineLevel.RootCodeGroup;

 

// 루트 코드 그룹의 하위 코드 그룹들의 이름과 설정된 권한 집합을 표시한다.

foreach (CodeGroup group in rootCodeGroup.Children) {

    Console.WriteLine("Code Group Name = {0},  PermissionSet Name={1}",

                    group.Name, group.PermissionSetName);

}

리스트2. 정책 수준의 최상위 코드 그룹과 그 하위 코드 그룹을 열거하는 예제 코드

리스트2는 정책 수준의 최상위 코드 그룹을 알아내고 그 최상위 코드 그룹의 하위 코드 그룹들을 표시하는 예제 코드이다. 간단한 예제이므로(핑계가 좋다. 사실은 귀찮아서... -_-;) 굳이 재귀 호출까지 사용하여 모든 코드 그룹 표시하는 만행을 저지르지는 않았다. -_-;

Adding a Code Group

개략적으로 코드 그룹을 열거하는 방법을 알아 봤으니 이제 코드 그룹을 추가하는 방법 역시 알아 보도록 하자. 대략 경험 깨나 해본 개발자라면 어렵지 않게 방법을 유추해 낼 수 있을 것이다. PolicyLevel 클래스가 RootCodeGroup 속성을 통해 최상위 코드 그룹을 반환하므로 이 코드 그룹에 새롭게 만든 코드 그룹을 추가하면 되지 않을까? 그대의 통밥은 대단하다. 그렇다. 추가하고자 하는 새로운 코드 그룹을 만들고 그 코드 그룹을 부모 코드 그룹에 추가하면 되는 것이다.

새로운 코드 그룹을 생성하기 위해서는 CodeGroup 객체를 만들면 된다. CodeGroup 클래스는 추상 클래스 이므로 직접 생성이 곤란하다. 대신 UnionCodeGroup 클래스를 사용하면 된다. 이 클래스는 다른 코드 그룹 클래스들에 비해 가장 많이 사용되는 클래스이다. .NET Framework Configuration MMC에서 코드 그룹을 추가하면 바로 UnionCodeGroup이 추가된다. 사실 필자도 다른 코드 그룹은 사용해 본적도 없다. UnionCodeGroup은 자기 자신 뿐만 아니라 자식들의 코드 그룹까지도 권한 계산을 포함하도록 해준다(이는 지난 포스트의 권한 계산에서 이미 설명한 바 있다).

코드 그룹을 생성하기 위해서는 먼저 이 코드 그룹이 어떤 멤버십 조건(membership condition)을 사용하는지 명시해야만 한다. 멤버십 조건은 ZoneMembershipCondition 클래스, SiteMemebrshipCondition 클래스, UrlMemebrshipCondition 클래스, AllMembershipCondition 클래스 등이 존재한다. 스마트 클라이언트 시나리오에서 어떤 멤버십 조건을 사용할 것인가가 결정되었다면 앞서 열거한 멤버십 조건 클래스들 중 하나를 선택하여 멤버십 조건을 생성하면 된다. 이들 클래스는 AllMembershipCondition을 제외하고 멤버십의 조건으로 인터넷 영역(zone), 사이트 이름, URL 중 하나를 매개변수로 취할 수 있다.

멤버십 조건을 생성했다면, 이제 코드 그룹이 가질 권한 집합을 명시하면 된다. 지난 포스트에서는 단순히 권한 집합이란 용어만을 사용했지만 권한 집합은 다시 이름을 갖는 명명된 권한 집합(Named Permission Set)과 그렇지 않은 권한 집합으로 나누어 볼 수 있다. .NET Framework Configuration MMC에서 권한 집합을 정의하면 이는 명명된 권한 집합을 정의하는 것이다. 명명된 권한 집합은 NamedPermissionSet 이란 클래스에 의해 표현된다. 이 클래스의 생성자에 이미 정의된 권한 집합(FullTrust, Internet, LocalInternet 등등의 이미 정의된 권한 집합들)의 이름을 주면 해당 권한 집합을 설정할 수 있다. 반면, 명명되지 않은 권한 집합은 PermissionSet 클래스(한글 MSDN 문서가 아직 준비 되지 않았단다...)를 통해 정의되며, 이 클래스의 인스턴스를 생성하고, FileIOPermission, SocketPermission 등의 구체적인 권한 클래스의 인스턴스를 생성하여 생성한 Permission 클래스의 인스턴스에 추가(AddPermission 메쏘드)해야만 한다.

말로만 하면 당췌 이해를 못하는 인간들이 많으니 예제 코드 서비스 들어간다.

// URL 멤버쉽 생성

UrlMembershipCondition membership = new UrlMembershipCondition("http://localhost.com/SmartClientBasic/*");

// 권한 집합 생성 (full trust)

NamedPermissionSet permissionSet = new NamedPermissionSet("FullTrust");

PolicyStatement policyStatement = new PolicyStatement(permissionSet);

// 추가할 코드 그룹 생성

UnionCodeGroup cg = new UnionCodeGroup(membership, policyStatement);

cg.Name = "테스트 코드 그룹";

cg.Description = "테스트용 코드 그룹임. 졸라 재미남...";

rootCodeGroup.AddChild(cg);

리스트3. URL 멤버십 조건을 사용하는 코드 그룹을 생성하고 설정하여 추가하는 예제 코드

리스트3은 코드 그룹을 생성하고 최상위 코드 그룹(All_Code)에 추가하는 예제 코드 이다. 앞서 리스트1리스트2에서처럼 CAS 정책 수준을 얻고 최상위 코드 그룹을 이미 알아 냈다고 가정하자. 먼저 UrlMembershipCondition 클래스를 통해 URL 멤버십 조건을 생성했다. 물론 멤버십 조건을 http://localhost.com/SmartClientBasic/* 으로 했다. 이제 NamedPermissionSet 클래스를 통해 FullTrust 권한 집합을 생성했다. 그리고 코드 그룹을 생성할 때, 만들어 놓은 멤버십과 권한 집합을 설정하였으며, 적절한 코드 그룹과 이름을 주었다. 마지막으로 최상위 코드 그룹에 대해 AddChild 메쏘드를 호출함으로써 코드 그룹을 추가 하였다.

리스트3에서 등장한 PolicyStatement 클래스는 코드 그룹이 갖는 권한 집합과 속성을 표시하는 클래스이다. 권한 집합까지는 알겠는데 코드 그룹의 속성이라니? 에이 C8 쑛같이 복잡하기도 하다... 지난 포스트에서 밝혔어야 했으나 글이 너무 길어지고 너무 복잡해 지는 것을 피하기 위해 언급하지 않았었는데, 지금 간략히 언급하기로 한다. 코드 그룹은 Exclusive 속성과 LevelFinal 속성을 가질 수 있다. 대략 설명하기 귀찮으니 MSDN 자료PolicyStatement 클래스의 Attribute 속성를 살펴보기 바란다. 지금도 필자는 너무 복잡타. 어찌 되었건 PolicyStatement 를 코드 그룹에 명시함으로써 코드 그룹의 생성이 완료되는 것이다.

Saving Policy

코드 그룹 추가가 끝났다면 이제 CAS 정책을 저장해야 한다. 저장하지 않은 CAS 정책은 현재 프로세스에 로드 된 닷넷 런타임에 의해서만 적용되는 코드 그룹이 되고 만다. 따라서 저장을 수행하여 영구적인 설정이 되도록 해야만 하며, 저장을 해야만 .NET Framework Configuration MMC에서 설정사항을 볼 수 있다. 저장된 CAS 정책은 닷넷 런타임이 새로이 시작될 때마다 읽혀지고 적용될 것이다.

저장하는 방법은 대단히 간단하다. SecurityManager 클래스의 SavePolicy 메쏘드를 달랑 호출하면 끝이다.

// CAS 설정 저장

SecurityManager.SavePolicy();

Sample - Creating Code Group

지금까지 설명한 것을 모두 모아, URL 멤버십 조건을 사용하며 FullTrust 권한을 갖는 코드 그룹을 Machine 정책 수준에 추가하는 예제 코드를 작성해 보자. 뭐 어려울 것도 없다. 앞서 보였던 예제 코드들을 적절히 조합하면 땡 이다. 리스트4의 AddUrlCodeGroup 메쏘드가 바로 그것이다. AddUrlCodeGroup 메쏘드는 URL 멤버십 조건을 사용하여 코드 그룹을 추가해 준다. 코드의 내용은 이미 앞서 대부분 설명한 내용이므로 더 이상 설명하지 않겠다. 사용방법 역시 졸라 쉽다. 고로 설명은 패스~~~ (아... 귀차니즘이여...)

public static bool AddUrlCodeGroup(string url, string name, string description)

{

    // Policy 레벨 열거를 얻는다.

    IEnumerator enumerator = SecurityManager.PolicyHierarchy();

    // Policy 레벨들(Enterprise, Machine, User) 중에서 Machine Policy를 찾는다.

    PolicyLevel machineLevel = null;

    while (enumerator.MoveNext()) {

        PolicyLevel level = (PolicyLevel)enumerator.Current;

        if (level.Label == "Machine") {

            machineLevel = level;

        }

    }

    if (machineLevel == null)

        throw new InvalidOperationException("Machine Policy를 찾을 수 없습니다.");

    // Root code group을 구한다.

    CodeGroup rootCodeGroup = machineLevel.RootCodeGroup;

 

    // 코드 그룹이 이미 존재하는가 확인한다.

    foreach (CodeGroup group in rootCodeGroup.Children) {

        if (group.MembershipCondition is UrlMembershipCondition) {

            if (group.Name == name) {

                return false;

            }

        }

    }

 

    // URL 멤버쉽 생성

    UrlMembershipCondition membership = new UrlMembershipCondition(url);

    // 권한 집합 생성 (full trust)

    NamedPermissionSet permissionSet = new NamedPermissionSet("FullTrust");

    PolicyStatement policyStatement = new PolicyStatement(permissionSet);

    // 추가할 코드 그룹 생성

    UnionCodeGroup cg = new UnionCodeGroup(membership, policyStatement);

    cg.Name = name;

    cg.Description = description;

    rootCodeGroup.AddChild(cg);

 

    // CAS 설정 저장

    SecurityManager.SavePolicy();

 

    return true;

}

리스트4. URL 멤버십을 사용하는 코드 그룹을 추가하는 유틸리티 메쏘드

리스트4에서 눈 여겨 볼 부분은 코드 그룹이 이미 존재하는가를 확인하는 부분이다. 루트 코드 그룹의 자식들에 대해 루프를 돌면서 매개변수로 주어진 코드 그룹의 이름이 존재하는가 확인하고, 만약 존재한다면 아무런 작업도 하지 않도록 한 것이다. 뭐 어려울 것이 없으므로 더 이상 설명은 필요하지 않으리라 본다. 위 코드가 너무 어렵다고 생각된다면 지금 당장 다른 직종으로 옮기는 것을 고려해 보라고 충고하고 싶다.

위 코드가 다 잘 이해 된다면, URL 멤버십이 아닌 사이트 멤버십을 사용하는 AddSiteCodeGroup 메쏘드도 만들어보길 권장한다. 이 역시 허벌나게 쉽다. UrlMembershipCondition 클래스 대신 SiteMembershipCondition 클래스를 사용하기만 하면 된다. 닭대가리가 아닌 다음에야 못할 이유가 없다고 본다. 꼬끼오~~~

Deployment of CAS Setting

지금까지 프로그램적으로 코드에 의해 CAS 정책을 수정하는 방법에 대해 노가리를 풀어봤다. 보다 중요한 것은 리스트4와 같은 코드를 어떻게 클라이언트까지 자동(?)으로 배포하고 수행시키냐는 것이다. 이제부터 CAS 정책을 배포하는데 필요한 몇 가지 권고 사항과 배포 방법을 살펴보도록 하겠다. 다양한 방법이 있을 수 있겠지만 여기서는 각 방법에 대한 상세한 설명은 생략하겠다. 왜냐고? 음... 그건... 필자가 이런 것을 컨설팅 해주는 것을 업으로 삼고 있는지라... 필자도 좀 먹고 살아야 할 거 아닌가? -_-; 그래도 권장되는 한가지 방법에 대해서는 좀 더 자세히 노가리를 풀어볼까 한다.

Selecting Membership Condition

먼저 배포할 CAS 정책에서 스마트 클라이언트가 포함될 코드 그룹이 어떤 멤버십 조건을 사용할지 결정해야 한다. 무식하게 기존 Internet 코드 그룹에 권한을 주는 짓을 하지 않을 것이라면 어플리케이션을 다운로드 할 URL 혹은 사이트로서 코드 그룹을 지정해 주는 것이 일반적이다. 혹은, 모든 DLL에 서명을 하고 StrongName 멤버십을 사용하는 방법도 생각해 볼 수 있지만 그다지 유연성이 높지는 않다. 왜냐면 다음 포스트에서 설명할 DLL이 다운로드 되는 것과 StrongName이 관련이 있을 뿐더러, 항상 동일한 .snk 파일을 사용해야 하는 등의 제약이 있기 때문이다. 쉽게 말해 StrongName 은 비추라고 할 수 있겠다.

보안 위협을 가장 적게 노출시키는 멤버십 조건은 URL 멤버십이다. 스마트 클라이언트 어셈블리(DLL, EXE)를 다운로드 할 URL에 대해 권한을 주도록 코드 그룹을 추가하는 것으로서 이 외의 URL은 기존의 Internet_Zone 혹은 LocalIntranet_Zone 코드 그룹에 속하게 되므로 권한에 제약을 받게 된다. 예로서 http://www.simpleisbest.net/Apps/SmartClientBasic/* 와 같은 URL을 사용하여 코드 그룹을 만들면 되겠다. URL 멤버십의 단점은 여러 디렉터리에서 어셈블리를 다운로드 하는 경우, 코드 그룹을 여러 개 추가하거나 보다 상위 디렉터리를 기준으로 URL을 주어야 한다는 점이다.

이외에 생각해 볼 수 있는 코드 그룹 멤버십은 사이트 멤버십이다. 사이트를 지정하고 그 사이트에서 다운로드 하는 어셈블리들에게 보다 완화된 권한을 주는 것이다. 사이트 멤버십을 사용하면 좋은 경우는, 필자가 관여된 P 건설 프로젝트처럼 대형 프로젝트에서 여러 웹 서버가 서브 시스템으로서 사용되는 경우일 것이다. 이 프로젝트는 5개의 서브 시스템 모두 스마트 클라이언트를 사용했었는데, 서브 시스템마다 서버의 DNS 이름이 달랐다. URL 멤버십을 사용한다면 최소 5개의 코드 그룹이 필요할 것이다. 이 때 사이트 멤버십을 사용하면 코드 그룹 1개만을 추가할 수도 있다. 사이트 이름 역시 와일드 카드(*)를 사용할 수 있으므로 *.domain.com 과 같이 사이트를 지정하면 server1.domain.com, server2.doamin.com 등 domain.com 으로 끝나는 모든 사이트들에 대해 CAS 권한 설정이 가능하다.

Use FullTrust

추가할 코드 그룹의 멤버십 조건을 결정했다면, 코드 그룹에 어떤 권한을 줄지 생각해 봐야 한다. 결론부터 말하면, 필자는 눈 딱감고 FullTrust를 사용하라고 권장하고 싶다. 물론 보안을 고려한다면 권한은 적게 줄 수록 좋을 것이다. 만약 인트라넷 시스템이라면(스마트 클라이언트를 고려한다면 아직까진 99.99%가 인트라넷 시스템을 위한 것일 게다), URL 멤버십과 사이트 멤버십은 커다란 보안 구멍을 의미하지 않는다. 게다가 일부 닷넷의 기능들(대표적으로 P/Invoke, Reflection 등)은 FullTrust가 아니면 작동조차 하지 않기 때문에 SecurityException 발생을 피할 수 있는 가장 편리한 방법이 FullTrust를 사용하는 것이다.

FullTrust를 사용하지 않으면, 필요한 권한들 만을 묶어서 새로운 권한 집합을 만들어 주어야 하는데, 이것 역시 만만한 작업이 아니기에(이 포스트에서는 설명하지 않았다) 더욱 FullTrust를 권장하는 바이다. 본인이 매우 용감하며, 보안 허점을 추호도 용서하지 못하겠다는 정의감에 불탄다고 생각된다면, MSDN을 좀더 뒤져서 리스트4에 권한 집합을 생성하는 코드를 추가해야 할 것이다.

Packaging CAS Policy

코드 그룹과 권한을 결정했으면, 이것을 클라이언트로 배포하기 위한 패키지를 만들어야 한다. 몇 가지 방법이 있을 수 있다. 첫째로 MSI(Microsoft Installer) 패키지로 만들어 설치하는 방법이다. 작성법은 간단하다. 먼저 리스트4와 같은 코드를 포함하는 DLL을 작성한다. 그리고 이 DLL에 Installer 클래스를 추가한다(Installer 클래스에 대해서는 구질구질하게 여기서 설명하지 않겠다). 이 Installer 클래스의 생성자 혹은 Install 메쏘드의 오버라이드에서 리스트4의 AddUrlCodeGroup을 호출하도록 한다. 필요하다면 URL, 코드 그룹의 이름 등을 하드 코드 하는 것도 주저하지 말자. DLL 작성이 완료되면 installutil.exe를 이용하여 테스트를 수행해 본다.

이제 .MSI 패키지를 작성하기 위해 비주얼 스튜디오에서 설치 프로젝트를 만든다. 설치 프로젝트의 Custom Action 에 앞서 작성한 DLL을 포함시킨다. 이렇게 하면, MSI 패키지에 의해 설치 최종 단계에서 Custom Action 에 등록된 DLL 들이 installutil.exe을 통해 수행되게 되므로 CAS 설정을 배포할 수 있는 것이다. 작성한 MSI 패키지를 웹 서버에 올려놓아 최종 사용자들이 다운로드 받아 MSI를 설치하도록 유도하는 웹 페이지를 만들면 된다. 간단하지 않은가?

두 번째 방법은 CAS 설정을 수행하는 닷넷 어플리케이션 EXE를 만드는 것이다. 리스트4를 참조하여 CAS 설정을 수행하는 exe를 만들고 이것을 압축하여 웹 서버에 올려놓고 최종 사용자들이 다운로드하고 수행하도록 유도한다. 이때 반드시 압축해야 한다. 그렇게 하지 않으면 작성한 exe를 독립 스마트 클라이언트로 인식해 버릴 것이며 독립 스마트 클라이언트는 CAS 보안 검사에 의해 리스트4와 같은 코드를 수행할 권한이 없다!

세 번째 방법은 ActiveX를 사용하는 것이다. 먼저 리스트4와 같은 코드를 포함하는 닷넷 DLL을 만든다. 그리고 C++를 이용하여 간단한 ActiveX 컨트롤을 만들고(UI는 없는 ActiveX 일 것이다), 이 ActiveX 컨트롤에서 닷넷 엔진을 호스팅하여 작성해 놓은 닷넷 DLL을 호출하도록 작성한다. 이제 ActiveX DLL과 닷넷 DLL을 하나의 CAB 파일로 만들고 웹 페이지에 끼워 넣으면 자동으로 CAS 설정이 배포될 것이다. 말은 쉽지만 웬만한 COM 및 닷넷 지식으로는 엄두도 내기 힘든 기법이다. 사용자가 수동으로 설치하는 액션이 필요 없다는 장점이 있지만 구현의 난이도가 매우 높다.

일반적으로 무리 없이 적용 가능한 방법은 첫 번째로 제시한 MSI를 이용하는 방법이다. 왜 그런고 이제 설명하도록 하겠다. 첫째 이유로, 대부분의 클라이언트 PC는 닷넷 프레임워크가 설치되어 있지 않다. 따라서 닷넷 프레임워크를 설치하는 일련의 설치 작업이 거의 99% 이상 필요하기 때문이다. 이런 이유로 닷넷 프레임워크를 설치하는 MSI 패키지를 만들면서 슬쩍 CAS 설정을 수행하도록 하면 되는 것이다.

두 번째 이유로 대부분의 어플리케이션은 고정 불변의 DLL 들을 포함하곤 한다. 이들 DLL의 대표적인 예는 오피스에 대한 Interop DLL, 상용 컨트롤에 대한 DLL 들이다. 이렇게 고정 불변의 DLL들을 스마트 클라이언트 시나리오에 의해 배포하는 것보다는 최초의 1회 설치로서 클라이언트에 배포해 버리는 것이 관리적으로도 편리할 뿐 더러, 어플리케이션을 최초로 사용하는 사용자들에 대해 응답속도를 올릴 수 있는 팁이 된다. 따라서 설치 패키지를 만드는 것이 상당히 자연스러운 작업이 될 것이며, 이 때 CAS 설정을 같이 해주자는 것이다.

세 번째 이유로서 스마트 클라이언트 시나리오로 배포되지 않는 Unmanaged DLL 들 역시 클라이언트에 배포해야 할 상황은 자주 발생하곤 한다(크리스탈 리포트는 managed DLL과 unmanaged DLL로 구성되어 있다). 스마트 클라이언트에서 상용 ActiveX 컨트롤을 사용한다면 이 ActiveX 컨트롤을 배포해야 할 것 아닌가? 그렇다면 당연히 배포 패키지를 필요로 할 것이다.

이러한 이유로서 초기 1회용 배포 패키지를 만드는 것은 전혀 이상한 작업이 아니다. 앞서 말한 것처럼 고정 불변의 닷넷 DLL과 스마트 클라이언트 시나리오로 배포되지 않는 unmanaged DLL들을 배포하는 MSI 패키지를 만들면서 Custom Action에서 CAS 설정을 하도록 MSI를 작성한다. 그리고 이 MSI에 닷넷 프레임워크를 선행적으로 설치하도록 해주는 부트스트래퍼를 설정한다. 이 부트스트래퍼는 닷넷 어플리케이션을 설치하기 전에 닷넷 프레임워크가 설치되어 있는지 검사하고, 설치 되어 있지 않다면 닷넷 프레임워크를 먼저 설치해 주는 역할을 하므로 닷넷 프레임워크가 설치되지 않은 사용자들을 위해서도 안성맞춤이 될 것이다. 부스트래퍼에 대한 상세한 내용은 다음 MSDN 자료를 참고하기 바란다.

닷넷 프레임워크와 고정 DLL 및 unmanaged DLL 그리고 CAS 설정을 포함하는 최종 MSI 패키지를 만들었다면 아마도 이것이 여러 파일들(setup.exe, dotnetfx.exe, *.MSI 등)로 구성되어 있을 것이므로 알집, WinRAR 등의 유틸리티를 통해 단일 압축 exe로 작성하여 웹 서버에 올려놓으면 된다. 사용자들은 단순히 이 exe를 다운로드 받아 수행하면 된다. 이렇게 함으로써, 클라이언트 PC에 닷넷 프레임워크는 물론이요, CAS 설정까지 유도할 수 있으므로 일석 이조의 효과를 낳게 된다.

지금까지 설명한 배포 방법을 보다 상세하게 설명할 수 없음을 독자들은 이해해 주기 바란다. 그 내용이 간단하지 않기 때문에 여기서 구체적으로 예를 들어 설명할 수 없기 때문이다. 물론 필자의 귀차니즘 역시 한 몫 단단히 했음은 두말할 것도 없다. 이 정도를 설명한 것도 필자의 상당한 노하우이므로 이 정도로 만족해 주기 바란다. 그리고 직접 함 시도해 보기를 강력히 권장하는 바이다. 누누이 강조하지만 눈 도둑만으로는 전혀 실력이 향상되지 않는다 !!!

What's Next

이번 포스트에서는 프로그램적으로 CAS 정책을 변경하는 방법에 대해 살펴보았고 구체적인 예제 코드 역시 제공하였다. 그리고 CAS 정책을 배포하기 위한 몇 가지 권고 사항과 배포 방법을 살펴보았다. 점점 포스트가 날림이 되는 것 같아서 영 쮭쮭하지만 그래도 질질 끌리는 것보다는 나을 것 같아서 잽싸게 글을 마무리했다. 불만있으면 필자를 찾아 오도록... -_-;

다음 포스트에서는 스마트 클라이언트 시나리오에서 DLL이 다운로드 되는 과정을 살펴보도록 하겠다. 당췌 스마트 클라이언트 시나리오에서 DLL이 다운로드되는 규칙을 알 수 없다고 하소연하거나 스마트 클라이언트에서 최신 버전이 다운로드 되지 않는다고 하소연 하는 사람들은 다음 포스트에 관심을 가져보기 바란다.



Comments (read-only)
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / wishy / 2006-05-08 오전 8:48:00
^^ 감사합니다.
다음포스트가 벌써부터 기대됩니다^^^^^^
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 찌유니아빠 / 2006-05-09 오전 8:18:00
^^
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 아드레날린 / 2006-05-11 오후 12:39:00
수고하셨습니다~! 항상 많은 도움이 됩니다....
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 이승용 / 2006-09-08 오후 8:47:00
강의 잘 보았습니다. 언제나 도움이 되어 주셔서 감사합니다.
이번에 스마트 클라이언트로 탐색기를 구현했는데 위의 코드로 입력하고 난 후 실행하니 all_code 그룹의 하위에 새로운 그룹이 생성 되는것을 볼 수 있었습니다. 문제는 이렇게 all_code 그룹하위 새로운 그룹을 생성했을 경우에 있을 경우 예외가 발생합니다.
테스트 결과 수동으로 Internet_zone의 하위에 새로운 자식코드 그룹을 추가하여 권한집합을 fullTrust로 설정하니 문제없이 작동을 한다는 것입니다.
이유가 뭘까요?
all_code 그룹 하위의 Internet_zone에 새로운 자식코드 추가를 위와같은 코드로 만든다면 어떻게 해야하나요?

쥔장님의 수고에 항상 고맙게 생각하고 있습니다..
그럼 수고하세요..~
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2006-09-12 오전 9:46:00
all_code 하위에 생성되더라도 문제가 없어야 합니다.
적어도 제가 테스트 한바로는 아무런 문제가 없었습니다만... (테스트를 잘못했나? -_-)
Internet_Zone 밑에 추가하는 것은 매우 쉽습니다.
RootCodeGroup 바로 밑에 Internet_Zone이 존재하므로 그것을 찾고(foreach 문으로)
찾은 Internet_Zone 코드 그룹의 하위에 새로이 코드 그룹을 생성해 넣으면 됩니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 힘들어 / 2006-09-12 오후 4:57:00
강좌 잘 보고 있어요 정말 감사합니다. 저도 저희 회사에 스마트 클라이언트를 도입하려고 계속 보고 있는 중인데요 .
위 강좌와 같이 설정해도 상용 컨트롤들은 역시나 에러가 나네요 ㅠㅠ
fiddler 로 확인해보니 304 에러인데 도저히 모르겠어요 ㅠㅠ;;;
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2006-09-12 오후 5:36:00
상용 컨트롤이 에러가 난다고 함은 SecurityException 이 발생한다는 것인가요?
단순히 에러가 난다고 하지 마시고 구체적인 예외 종류와 메시지를 알려주셔야 도움을 드릴 수 있습니다.
(질문하실 때의 기본중에 가장 기본입니다)

SecurityException이 발생한다면 CAS 보안 문제일 가능성이 높지만 그렇지 않은 다른 예외인 경우,
해당 상용 컨트롤의 라이센스 문제일 가능성이 높습니다.
최신 버전에 대해서 테스트 해보진 못했지만, FlexGrid, Infragistics 류는 FullTrust 설정을 해준 경우에
SecurityException을 발생하지 않습니다. 즉, 아무 문제가 없어야 한다는 것이지요.
브라우저의 캐시를 모두 지우고, gacutil.exe를 이용하여 다운로드 캐시도 모두 지워보고 다시
시도해 보십시요. 물론 CAS 설정이 올바르게 되어 있다는 가정 하에서 입니다.

ChartFx의 경우 SecurityException은 아닙니다만 대신 라이센스와 관련된 Exception이 발생합니다.
이는 ChartFx 자체가 EXE(정확히 말해서 Entry Assembly)에 기록된 라이센스 정보를 찾으려고 하지만 스마트 클라이언트는
그러한 것이 없으므로 정식으로 구매한 제품일지라도 라이센스 관련 예외가 발생하는 겁니다.

ChartFx에 대한 내용은 제 글인 불가능은 없다... 대략 귀찮을 뿐...(http://www.simpleisbest.net/archive/2005/05/27/153.aspx) 이란 글을 읽어 보십시요.
구체적이고 일반적인 해결책을 제시하진 않았지만 무엇이 문제이고 어떻게 해야하는지 대충 감을 잡으실 수 있을 겁니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 힘들어 / 2006-09-13 오후 2:12:00
제가 너무 몰라서 쥔장님 글을 이해하기도 힘드네요. 다시 에러메세지를 적어볼께요 .

**************
처리되지 않은 'System.IO.FileNotFoundException' 형식의 예외가 %ED%9A%8C%EC%82%AC%EA%B8%B0%EC%B4%88%EC%A0%95%EB%B3%B4[2].exe에서 발생했습니다.

추가 정보: 파일이나 어셈블리 이름 AxInterop.MSComDlg 또는 여기에 종속되어 있는 파일이나 어셈블리 중 하나를 찾을 수 없습니다.
**************

베이스디렉토리도 맞추고 CAS 셋팅도 쥔장님 글을 보고 설정했으나 저런 에러가 뜨네요 ...
도와주세요 쥘쥘 ㅠㅠ
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2006-09-13 오후 3:05:00
예외 메시지 대로인데요... -_-; AxInterop.MsComDlg 어셈블리를 웹 서버에 올려두십시요.
사용하시는 상용컨트롤이 ActiveX 인듯 합니다. ActiveX를 닷넷에서 사용하면 ActiveX에 대한
래퍼 어셈블리(DLL)가 생성됩니다. 이 어셈블리 역시 스마트 클라이언트 시나리오에 의해 다운로드 되어야만
합니다.

ActiveX를 스마트 클라이언트 화면에 사용하실때는 주의하셔야 할 사항이 있습니다.
ActiveX는 닷넷 어셈블리가 아니므로 클라이언트에 자동으로 다운로드 되고 설치되지 않습니다.
스마트 클라이언트는 닷넷 어셈블리에 대해서만 자동으로 다운로드될 뿐입니다.
ActiveX는 별도로 설치 패키지를 만들던가 일반 웹 페이지에서 사용하듯이 CAB으로 배포를 해야 합니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 힘들어 / 2006-09-13 오후 4:04:00
웹 서버에 같이 올려두라는 말씀은 같은 베이스디렉토리에 올려두란 말씀맞나요 ? 현재 같이 올라가 있는데 ;;
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / CAS / 2006-10-18 오후 7:16:00
CAS 셋팅이 되어 있는지 안되어 있는지 asp.net에서 알수 있는 방법은 없는지요?

여기저기 자료를 찾아봐도 찾을 수가 없네요 ㅠ.ㅠ
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2006-10-18 오후 10:16:00
관심이 가는 CAS 세팅은 클라이언트의 CAS 이겠지요?
클라이언트의 CAS 설정을 서버인 ASP.NET에서 알 방법은 없습니다만...
저의 경우 ActiveX를 이용하여 CAS 설정 여부를 판단했습니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / CAS / 2006-10-18 오후 11:20:00
답글 감사합니다.

추가 질문 하나만 더 하겠습니다.
ActiveX에 대한 질문인데요 혹 C#으로 ActiveX 가능한가요?

쓰신글을 보니C++로 ActiveX를 작성한다라는 걸 봤습니다만..
C++이나 VB 말고 C#으로 ActiveX를 만들 수 있나요?

죄송하지만 이건 자료를 찾아 보지 않고 답글을 보고 제가 바로 작성한 글 입니다.
자료는 따로 찾아 보도록 하겠지만.... 답글 부탁드립니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2006-10-18 오후 11:35:00
C#으로 ActiveX 작성이 가능합니다만...
클라이언트에 닷넷이 설치되어 있어야만 하고, 일반적으로 ActiveX를 배포하는데 사용하는 CAB 파일은
C#으로 작성한 ActiveX를 배포할 수 없답니다.
(일반 ActiveX는 regsvr32.exe를 등록하는데 쓰지만 C#으로 작성한 ActiveX는 regasm.exe를 쓰기 때문에...)
그래서 C++ 로 작성한 것이지요.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / ari / 2006-10-26 오후 6:53:00
명명되지 않은 권한 집합을 생성할때 집합이름은 어떻게 샛팅하나요?

PermissionSet permissionSet2 = new PermissionSet(PermissionState.None);
permissionSet2.AddPermission(new FileDialogPermission(FileDialogPermissionAccess.Open));
permissionSet2.AddPermission(new IsolatedStorageFilePermission(PermissionState.Unrestricted));
permissionSet2.AddPermission(new SecurityPermission(SecurityPermissionFlag.AllFlags));
permissionSet2.AddPermission(new UIPermission(UIPermissionClipboard.AllClipboard));
permissionSet2.AddPermission(new PrintingPermission(PrintingPermissionLevel.AllPrinting));

이런식으로 했는데 작동안하는듯합니다. ^^;;;
어떤 코드를 추가해야되는지요 ?
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / ari / 2006-10-26 오후 7:49:00
해결했습니다. ^^;
NamedPermissionSet permSet = new NamedPermissionSet( "SmartClientSet", PermissionState.None );
요러케..~~

암튼 여기서 많이 공부하고 가네요.~~ 감솨감솨
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 쿠쿠쿠111 / 2006-12-02 오후 3:11:00
CAS 설정을 site 멤버쉽을 가지도록 작업해서, 배포를 했는데, .Net Framework SDK가 설치된 개발장비에서는 configuration 도구로 설정 여부를 확인할 수 있는데, 일반 클라이언트들에서는 .Net Framework 2.0을 설치해도 configuration 도구가 생성되지 않아, 설정이 제대로 됬는지 확인해 볼수가 없네요.
물론 해당 스마트클라이언트가 주어진 권한대로 잘 작동하는지 확인해 보면 되지만, 그렇게 말고, 배포 직후 바로 확인할 수 있는 방법은 없나요?
모든게 처음이라 짚어나가야 할게 넘 많네요.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2006-12-04 오후 2:04:00
그러게요... 2.0 런타임에는 Configuration 도구가 빠져있지요.
제가 배포 직후 확인하는 방법은... 직접 security.config 파일을 까본다는...
아니면 USB 메모리에 CAS를 읽어 트리로 보여주는 프로그램을 들고 다니면서
보거나 테스트 프로그램을 작성해서 실행시켜보는 수법을 씁니다만...
쩝... 저도 별 도움이 안되네요... -_-;
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 쿠쿠쿠111 / 2006-12-04 오후 2:26:00
ㅋㅋㅋ, 감사^^. security.config를 까니까 바로 확인되네요^^.뭐, 굳이 트리로까지 보여지지 않아도 상관없습니다.
도움 만빵입니다....
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / OTS / 2007-01-02 오후 4:29:00
# 스마트클라이언트 DebugIEHost.log 좀 봐 주세요. 2007-01-02 오후 2:06 OTS
안녕하세요?
스마트클라이언트 초보자입니다.
현재 테스트중인데... 닷넷 기본 컨트롤인 DataGrid에는 Local 및 Client 모두 데이타가 이상없이 잘 올라옵니다.
그런데 그리드 컴포넌드(C1FlexGrid)를 올려놓고 테스트를 해 보니 Local에서는 잘 올라오는데 Client에서는 그리드가 나타나질 않네요...
CAS 설정을 모두 다 해주었고요... DebugIEHost.log를 아래에 복사하였습니다.
고수님들 아래 로그 확인해여 조언 부탁드립니다.

아래 로그는 클라이언트 PC에 저장된 로그입니다.

Creating security manager

Microsoft.IE.Manager: Microsoft.IE.Manager: unique id lgth = 42
...... 중략 ......
Microsoft.IE.SecureFactory: Trying to create instance of type http://192.168.0.46/frmTest/ClientModule.dll#ClientModule.FXGrid
Microsoft.IE.SecureFactory: System.Reflection.TargetInvocationException: 호출 대상이 예외를 Throw했습니다.
---> System.Security.SecurityException: 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089' 형식의 사용 권한을 요청하지 못했습니다.
...... 중략 ......
위치: ClientModule.FXGrid.InitializeComponent()
위치: ClientModule.FXGrid..ctor()
실패한 작업:
InheritanceDemand

---이하 생략---
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2007-01-02 오후 4:32:00
OTS 님//
나타난 오류는 SecurityException 으로서 명백한 CAS 권한 오류입니다.
FXGrid 클래스의 InitializeComponent에서 SecurityPermission이 없어서 발생하는 예외입니다.
CAS 설정을 다 해주셨다고 했는데 정확히 수행되었는지 확인해 보시기 바랍니다.

http://www.simpleisbest.net/archive/2006/04/28/612.aspx#Screen5 에 설명된 유틸을 사용하여
CAS 권한을 확인해 보시는 것도 좋은 방법입니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / OTS / 2007-01-13 오전 10:29:00
위의 Creating Code Group Sample을 보고 Exe 파일로 하나 만들었습니다.
프레임웍이 1.1만 설치된 경우는 아주 잘 됩니다.
그런데 프레임웍이 1.1과 2.0 2개가 동시에 설치된 곳은 문제가 발생되네요...

확인해 본 결과 2개의 버전이 동시에 설치된 곳은 CAS 셋업이 1.0에만 되고 2.0에는 자동 셋업이 되지 않았더군요..
그래서 수작업으로 2.0에 셋업을 해 주니 스마트클라이언트가 이상없이 잘 돌아갑니다.

2개의 버전이 동시에 설치된 경우는 소스에 따로 설정을 해 줘야 하는게 있나요?
조언 부탁드립니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 오~ 정말 대단해 / 2007-07-20 오전 10:58:00
아~ 넘도 찾던 자료네요.. 넘 감사드립니다..

근데요~ 저기.. mci를 작성할대요.. Custom Action 이란데다 dll를 추가하라고 하셨는데... 음.. Custom Action 이것이 멀 의미하는건가요~
2005로 작업중인데... 그런 속성을 제가 못찾겠네요~~
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 오~ 정말 대단해 / 2007-07-20 오전 11:34:00
아~ 그것이... 보기>사장자 지정 작업 이구요...
아무튼 잘 되네요~ 넘 감사드립니다...

#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 비스타에서 CAS 설정... / 2007-07-24 오후 6:16:00
위코드를 사용하여 클라이언트의 CAS를 설정합니다.
그런데 비스타에서 SecurityManager.SavePolicy(); 코드 부분에서 오류가 납니다.
"Enterprise 정책 수준의 보안을 저장할 수 없습니다."
이거 하신분 리플 좀 달아 주세요.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2007-07-25 오후 9:47:00
SavePolicy() 가 호출되면 security.config 파일이 수정됩니다.
이 파일은 Vista에서 관리자 권한이 있어야만 수정이 가능한 파일이므로
관리자 권한이 없어서 발생하는 오류일 것으로 추정됩니다.
관리자 권한이 있는 상황에서 예제 코드를 수행해 보십시요.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 정해봉 / 2007-07-26 오전 11:39:00
security.config 파일이 클라이언트에 있는 파일이죠?
분명 Administrator 계정에서 실행을 하는데 파일 수정 권한이 없다는게 이상해요.
보완이 엄청 강화 됬군요. 비스타...
어쩐다...
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / GG / 2007-08-09 오후 12:12:00
"CAS 설정을 수행하는 exe를 만들고 이것을 압축하여 웹 서버에 올려놓고 최종 사용자들이 다운로드하고"
부분에서 압축을 한다는게 어떤것을 의미하는 건가요.
#re: 쥔장 지식과경험을 도둑질 해가는 느낌이라고 할까나~ / 강희기 / 2007-08-30 오전 11:41:00
요놈도 다읽었당..으흐흐
나중에 정독하러 또 올께용~ 보고또보고~
포스트 캄솨캄솨~
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / Help~ / 2007-11-27 오전 12:59:00
위의 Creating Code Group Sample을 보고 Exe 파일로 하나 만들었습니다.
프레임웍이 1.1만 설치된 경우는 아주 잘 됩니다.
그런데 프레임웍이 1.1과 2.0 2개가 동시에 설치된 곳은 문제가 발생되네요...

확인해 본 결과 2개의 버전이 동시에 설치된 곳은 CAS 셋업이 1.0에만 되고 2.0에는 자동 셋업이 되지 않았더군요..
그래서 수작업으로 2.0에 셋업을 해 주니 스마트클라이언트가 이상없이 잘 돌아갑니다.

2개의 버전이 동시에 설치된 경우는 소스에 따로 설정을 해 줘야 하는게 있나요?
조언 부탁드립니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 오택성 / 2007-12-27 오후 9:05:00
안녕하세요? 오랜만에 들어와 보네요...
한가지 문의드릴게 있습니다.
위 소스로 cs 프로그램을 만들어 실행시켜 보니 닷넷 1.1 과 2.0 버전이 동시에 설치되어 있는 경우
1.1에 권한이 설정되고 2.0에는 설정이 되지 않아 스마트 클라이언트 로드가 되지 않네요...
조언 부탁드립니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2007-12-28 오전 12:51:00
1.1과 2.0이 모두 설치되어 있는 경우 위 코드가 어떤 런타임에 의해 수행되는가에 따라
적용되는 것이 다릅니다. 위 코드가 1.1 런타임에 의해 수행되면 1.1의 CAS 설정이 바뀌고
2.0 런타임에 의해 수행되면 2.0의 CAS 설정이 바뀌게 됩니다.
둘다를 수정하려면 1.1 런타임과 2.0 런타임에 위 코드가 수행되도록 해야 하는데,
이렇게 프로그램을 작성하기란 쉽지 않다는... -_-;
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 뇌사상태 / 2008-07-08 오후 4:29:00
안녕하세요~~ 쥔장님께서 넘도 좋은 정보를 주셔서.. 성공적으로 서비스를 오픈했는데요~ 근데.. 비스타에서 문제가 발생했습니다..

// CAS 설정 저장
SecurityManager.SavePolicy();

위 설정 저장부분에서 administrator계정에선 정상 작동하지만 일반 사용자 계정에선 "Enterprise 정책수준으로 저장할수없다"고 하는데요~
다른 방법이 있을까요~~

그럼 수고하세요~~
#이런.. / 뇌사상태 / 2008-07-08 오후 4:45:00
위에 같은 질문이 있네요.. 분명 확인을 하고 질문을 올린건데.. 쩝...

근데요.. 그럼, "Vista에서 관리자 권한이 있어야만 수정이 가능하다면".. 일반계정을 가진 사용자한테는 서비스가 불가능한건가요~~
#질문이 있는데요 / 열심히살자 / 2008-10-11 오전 10:44:00
만약에
Addchild 를 한다음에
그 밑에 또 하위 그룹을 추가할려면 어떻게 해야 하나요?
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2008-10-11 오후 3:53:00
CodeGroup은 AddChild 메쏘드를 제공합니다.
AddChild 로 추가한 코드 그룹에 대해서 AddChild 를 추가하면 하위에 추가가 가능합니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 샵질쟁이 / 2008-10-29 오후 2:34:00
좋은 정보 감사합니다.
CAS 설정에서 위 코드가지고 SmartClient 라는 이름의 Code Group 을 추가했습니다.
근데 http://localhost.com/SmartClient , Full Trust 로 설정이 된걸 확인했습니다.
익스플로러에서 페이지를 읽어서 실행(ODBC.ini 파일 읽어서 메세지 박스에 표시하는 부분입니다.
)하면 System.Security.Permissions.FileIOPermission, mscorlib, Version = 2.0.0 CUlture=neutral, Public Key Token = b77a561934e089 형식의 사용권한을 요청하지 못했습니다...라고 나옵니다.
근데 Internet_Zone 의 속성을 Full Trust 로 바꾸면 제대로 실행이 됩니다.
SmartClient 코드 그룹으로 안되는 건 왜일까요????

세심하게 정리한 자료 잘 보고 있습니다. 수고하십시오.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2008-10-29 오후 5:31:00
URL 코드 그룹을 지정하실 때에는 URL에 *.dll 혹은 *.exe, *.* 등과 같이
와일드 카드를 사용하셔야 합니다. 단순히 디렉터리 이름으로 끝나는 URL로는
CAS 설정이 효과를 발휘하지 않습니다. 즉,
http://localhost.com/smartclient/*.* 와 같은 URL을 사용하여 코드 그룹을 지정하셔야
한다는 말이지요.

도움이 되셨기를......
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 그렇게 해도 안되네요 ㅠㅠ / 2008-10-31 오전 8:41:00
http://localhost.com/smartclient/*.* 설정했는데도 똑같이 안됩니다. internet 코드그룹을 Full trust 로 설정하면 되는데요
삭제하고 다시 해봐도 안되구요 제가 뭔가 잘못하고 있는것일까요 ???
회사에서 스마트 클라이언트로 사용할거라....internet 코드그룹을 Full trust 로 설정하는건 안되겠죠???
한번더 살펴봐 주십시오...수고하세요 ...
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2008-11-10 오후 12:09:00
혹시 Windows Vista를 사용하시나요? Windows Vista는 브라우저에서
액세스할 수 있는 파일들이 제한되어 있습니다.
CAS 설정을 통과했다 할지라도 Windows 권한에 의해 액세스 거부가 발생할 수 있습니다.
정확한 예외 메시지를 알려주십시요.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / simpleer / 2009-03-03 오후 9:52:00
vista에서 관리자 모드로 cas설정 마친상태구요, 파일쓰기/읽기 다 되는데, 참조 dll들이 동작을 안하는거같네요 ㅠㅠ 위에 브라우져에서 액세스 할수 있는 파일이 제한되어있다고 답글이 달려있는데 제한을 풀수 잇는 방법이 없을까요? XP에서는 정상적인데 비스타에서만 제대로 동작을 안하네요..깝깝....

#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2009-03-05 오후 2:37:00
Vista에서 제한이 있다는 말은 브라우저가 저 수준의 권한 모드에서 작동하기 때문에
읽고 쓸 수 있는 파일에 제한이 있다는 말입니다. 이 권한 모드를 상승시키기 위해서는
해당 웹 사이트를 신뢰할 수 있는 사이트에 등록해야 합니다.
Vista에서 IE7 브라우저가 갖는 제한에 대한 상세한 내용은 "보호 모드" 혹은 MIC(Mandatory Integrity Control)에 대한
자료를 살펴보시기 바랍니다.

도움이 되셨기를....
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 이현진 / 2009-03-25 오후 5:47:00
소중한 자료 고맙습니다.
위의 맛보기 예제를 실행하면 정상적으로 잘 나타납니다.
하지만 상용 컴포넌트(정품)를 올리니 실행이 되지 않는군요.
alone 모드에서는 잘 실행되는것으로 보아 CAS 설정 문제로 추정하여 CAS 설정까지 올렸는데..
여전히 실행이 되지 않습니다.
신뢰 사이트도 등록하였습니다.
추가로 확인해야 할 사항이 있나요?
답변주시면 감사하겠습니다.

window XP sp3, IE7 입니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 이현진 / 2009-03-25 오후 6:33:00
어셈블리 확인을 해보니 internet_zone 으로 되어 있네요.
CAS 에 URL 설정을 새로 추가 했는데.. 그 설정으로 확인이 안되네요.
internet_zone 설정을 FullTrust 로 바꾸니 실행이 되네요..

internet_zone 에 자식코드 그룹을 추가 해도 마찬가지로 안되는군요.
머가 잘못된건지 모르겠네요.
답변 주시면 감사합겠습니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 이즈 / 2009-05-07 오후 3:47:00
이제 막 스마트 클라이언트를 공부하게 된 사람 입니다
다름이 아니라 그룹에 대한 권한을 생성하는 프로그램으로 배포를 마쳤습니다.
지금 제가 할려고 하는 흐름은 이렇습니다
a.aspx 파일에서 클라이언트의 코드그룹에 존재하는지 체크후 존재하지 않는다면 b.htm 페이지로 이동해서 cas에 관련 배포 페이지로 이동하게 됨니다
(b.htm페이지는 클릭온스로 만든 베포페이지)
그런데 cas 권한 프로그램을 설치후 다시 a.aspx페이지를 가도 아직 코드그룹이 존재하지 않는걸로 나옵니다.
다시 재 설치할려고 하면 이미 존재한다면 return을 시켰기때문에 생성할필요 없게 되고요
웹에서는 제대로 체크가 안되는거 같습니다
제가 생성하고 다시 생성코드 그룹을 삭제하고 체크하면 있는걸로 나올때도 있습니다.
캐시때문에 그런지
가장 문제점은 윈폼이나 배포에서 체크시에는 해당 코드그룹이 존재합니다
하지만 웹에서 코드그룹 체크에서는 실제와 다릅니다.
이유는 뭐고 어떻게 하는것이 가장 좋은 방법일까요?

다시 한번 설명드리면
현재 그룹 존재하지 않음
a.aspx -> b.htm (배포 설치) 후 다시 a.aspx페이지로 이동 또는 새창
a.aspx 페이지에서 코드그룹 존재유무 체크시 코드 그룹 존재하지 않는것으로 나옴
현재 브라우저는 IE 7.0 설정상태는 페이지 열때마다 로 설정했습니다.

#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2009-05-08 오후 2:13:00
안녕하세요.

CAS 설정은 어플리케이션 도메인이 시작될 때 읽혀 집니다. 변경된 사항은 어플리케이션 도메인이
재시작 되지 않는한 새로운 설정이 적용되지 않는다는 말이지요.
웹 페이지 내에서 CAS 설정을 확인한다고 하셨으니 브라우저 임베디드 스마트 클라이언트를
사용하신 것 같습니다만... 브라우저 임베디드 스마트 클라이언트는 최초의 어셈블리에 의해
어플리케이션 도메인이 생성되면 그 어플리케이션 도메인이 계속 재 사용됩니다.
따라서 변경된 CAS 설정이 읽혀 지지 않는 것 같습니다.

해결하는 방법은 CAS 설정을 읽어 들이는 코드를 별도의 어플리케이션 도메인을
생성하여 수행하도록 하는 것입니다. 어플리케이션 도메인을 생성하고 구동하는 방법에
대해서는 MSDN을 참고하시거나 월간 마소(몇 월호인지 기억이... -_-)에 기고한
제 글을 참고하시기 바랍니다.

도움이 되셨기를......
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 유무상 / 2009-05-14 오후 8:14:00
안녕하십니까...

강의 내용 잘보고 있습니다. 한가지 여쭤볼게 있습니다. 제가 스마트클라이언트를 접한지가 얼마 되지 않아서...
일단 브라우져Embedded 방식으로 개발을 하고 있는데요. 보안문제가 발생해서 CAS설정 모두 완료 후 로컬에선 잘돌아갑니다.
이후 클라이언트(다른 컴퓨터) 쪽으로 배포한 후에 보안문제가 발생한거 같습니다.

그래서 위의 예제처럼 CAS설정해주는 부분을 메소드로 만들어서 dll 로딩시 그 메소드를 호출하는 방식으로 작업을 했습니다.
역시 로컬에선 잘돌아가는데요...

다시 클라이언트 쪽에선 권한 오류가 나는데 제가 잘못된 방식으로 작업을 하고 있는건지 알고십습니다...

아래는 예외 텍스트 입니다.
************** 예외 텍스트 **************
System.Security.SecurityException: 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 형식의 사용 권한을 요청하지 못했습니다.
위치: System.Security.PolicyManager.PolicyHierarchy()
위치: System.Security.SecurityManager.PolicyHierarchy()
위치: fileClient.fileClient.PermisionYN()
위치: fileClient.fileClient.fileClient_Load(Object sender, EventArgs e)
위치: System.Windows.Forms.UserControl.On-Load(EventArgs e)
위치: System.Windows.Forms.UserControl.OnCreateControl()
위치: System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
위치: System.Windows.Forms.Control.CreateControl()
위치: System.Windows.Forms.Control.WmShowWindow(Message& m)
위치: System.Windows.Forms.Control.WndProc(Message& m)
위치: System.Windows.Forms.ScrollableControl.WndProc(Message& m)
위치: System.Windows.Forms.ContainerControl.WndProc(Message& m)
위치: System.Windows.Forms.UserControl.WndProc(Message& m)
위치: System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
위치: System.Windows.Forms.Control.ActiveXImpl.System.Windows.Forms.IWindowTarget.OnMessage(Message& m)
위치: System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
위치: System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
실패한 작업:
Demand
실패한 첫 번째 권한 형식:
System.Security.Permissions.SecurityPermission
실패한 어셈블리의 영역:
Trusted
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 블로그쥔장 / 2009-05-15 오후 1:43:00
CAS 권한 설정을 하기 위해서는 권한이 필요합니다.
따라서 브라우저 임베디드 스마트 클라이언트 DLL 안에서 CAS 권한 설정을 수행하는 코드는
권한이 없어서 위와 같은 오류를 유발하게 됩니다.
CAS 설정을 클라이언트 PC 상에 배포하기 위해서는 별도의 설치 파일을 사용하거나
ClickOnce 와 같은 별도의 권한 배포 방법을 사용해야 합니다.
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 유무상 / 2009-05-15 오후 2:47:00
햐~ 어렵네요...

어쨌든...왜 그런건지도 알았고...방법도 알았으니...다시 해봐야겠네요....

블로그쥔장님...감사...^^
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / manifest 방식으로는 불가능한가요? / 2009-05-20 오후 4:04:00
올려주신 주옥같은 포스트들 정말 잘 읽고, 많은 도움이 되었습니다.
CAS 권한설정하느는 것을 메니페스트로 해보려고 하는데요 어렵더군요...
자료 찾아가면서 해보고 있는데 막히는 부분이 있어서 여쭤봅니다.

하려는 작업은 임베딩되는 컨트롤에서 데이터베이스나 웹서비스를 호출하려고 하는데 권한이 없어서 안되더군요... ---;
그래서 메니페스트로 하면서 아래와 같은 예외를 만났습니다...
조언을 좀 부탁드리겠습니다.. 꾸벅...
제가 하는 방법이 과연 맞는 것인지... 하하

Creating security manager

Microsoft.IE.Manager: Microsoft.IE.Manager: unique id lgth = 44
Microsoft.IE.SecureFactory: Create SecureFactory() with security information
Microsoft.IE.Manager: Created secure factory
Microsoft.IE.SecureFactory: Creating instance of the object in the correct domain
Microsoft.IE.SecureFactory: pUrl = http://test.grid.com/Default.aspx">http://test.grid.com/Default.aspx">http://test.grid.com/Default.aspx">http://test.grid.com/Default.aspx
Microsoft.IE.SecureFactory: id = 86474707A347563747E276279646E236F6D630000000
Microsoft.IE.SecureFactory: link =
Microsoft.IE.SecureFactory: licenses =
Microsoft.IE.SecureFactory: deployment manifest = grid_prototype.control
Microsoft.IE.SecureFactory: Security options = ZoneEvidence, SiteEvidence
Microsoft.IE.Manager: Url = http://test.grid.com/Default.aspx">http://test.grid.com/Default.aspx">http://test.grid.com/Default.aspx">http://test.grid.com/Default.aspx
Microsoft.IE.Manager: UrlGetPartW returned 0
Microsoft.IE.Manager: UrlGetPartW returned 80070057
Microsoft.IE.Manager: CodeBase = http://test.grid.com
Microsoft.IE.Manager: Application =
Microsoft.IE.Manager: Found a codebase
Microsoft.IE.Manager: UrlCanonicalize returned 0
Microsoft.IE.SecureFactory: URL codeBase: http://test.grid.com/
Microsoft.IE.SecureFactory: URL application: <null>
Microsoft.IE.Manager: UrlCanonicalize returned 0
Microsoft.IE.Manager: Link is relative: replaced with http://test.grid.com/grid_prototype.control
Microsoft.IE.Manager: UrlCanonicalize returned 0
Downloading http://test.grid.com/grid_prototype.control
Microsoft.IE.DeploymentManifest: Deployment provider code base: http://test.grid.com/grid_prototype.control
Microsoft.IE.DeploymentManifest: Manifest requests install: False
Microsoft.IE.DeploymentManifest: Verifying deployment manifest
Microsoft.IE.DeploymentManifest: Signing certificate trust level: Trusted
Microsoft.IE.Manager: UrlCanonicalize returned 0
Microsoft.IE.Manager: Link is relative: replaced with http://test.grid.com/grid_prototype.dll.manifest
Microsoft.IE.Manager: UrlCanonicalize returned 0
Microsoft.IE.SecureFactory: Using application manifest: http://test.grid.com/grid_prototype.dll.manifest
Downloading http://test.grid.com/grid_prototype.dll.manifest
Microsoft.IE.SecureFactory: Microsoft.IE.InvalidManifestException: The manifest must contain exactly one dependent install assembly.
위치: Microsoft.IE.Manifest.ReadFirstDependentInformation()
위치: Microsoft.IE.Manifest..ctor(Uri url, String localPath)
위치: Microsoft.IE.ApplicationManifest..ctor(Uri url, String localPath)
위치: Microsoft.IE.ApplicationManifest.Download(Uri url)
위치: Microsoft.IE.SecureFactory.CreateInstanceWithSecurity2(Int32 dwFlags, Int32 dwZone, String wszSite, String wszId, String wszConfig, String wszLicenses, String wszDeploymentManifest)
Microsoft.IE.SecureFactory: LOG exception
Microsoft.IE.SecureFactory: Creating log entry ?FusionBindError!name=grid_prototype.dll grid_prototype.GridPrototype
Microsoft.IE.SecureFactory: Logging to file C:\Documents and Settings\Administrator\Local Settings\Temporary Internet Files\Content.IE5\KEW2SD1E\CAAJ2NVN.HTM

참고한 사이트 : http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx
#re: 스마트 클라이언트, 그것을 알려주마 (VII) : CAS Deployment / 한국투자 / 2009-09-15 오후 3:42:00
먼저 정말 감사하다는 말씀 드립니다...
가능한 많이 배워가고자 답글까지 전부 읽고 있는데, 위에 제가 궁금했던 내용을 올리신분이 계시군요..
다름이 아니라 CAS 설정후에도 기존에 로드되어 있는 DLL은 계속 기존의 CAS의 영향아래 있다는 글입니다.
쥔장님의 답글을 보고, 별도의 어플리케이션 도메인을 생성하여 이러한 문제를 풀어보려고 했으나
AppDomain 을 생성하는것도 보안에 걸리는거 같습니다.
저는 CAS설정후에 IE를 재시작하지 않고, DLL을 로드하려고 합니다.
혹시 좋은 팁이나, 참고할만한 것이 있다면 부탁드립니다.
(어플리케이션 도메인 관련된 내용을 마소 몇월호에 기고하셨는지라도 알려주시면 감사하겠습니다.)