COM+의 역할 기반 보안(Role-Based Security)과 ASP에서 컴포넌트 사용하기

등록일시: 2002-03-15 이전,  수정일시: 2018-04-07 12:10
조회수: 29,023
본문은 최초 작성 이후, 약 22년 이상 지난 문서입니다. 일부 내용은 최근의 현실과 맞지 않거나 동떨어져 있을 수 있으며 문서 내용에 오류가 존재할 수도 있습니다. 또한 본문을 작성하던 당시 필자의 의견과 현재의 의견에 많은 차이가 존재할 수도 있습니다. 이 점, 참고하시기 바랍니다.

본문에서는 데이터베이스의 데이터를 읽거나 기록하는 작업 같이 보다 일반적인 기능을 갖고 있는 컴포넌트를 비롯해서, 시스템이나 네트워크상에 존재하는 보다 핵심적인 리소스에 접근할 수 있는 기능을 갖고 있는 컨포넌트를 사용하는 ASP 프로그램을 개발할 때 빈번하게 접하게 될 수 밖에 없는 권한과 관련된 문제점을, 역할 기반 보안(Role-Based Security)을 사용해서 빠르고 직관적으로 해결하는 방법에 관해서 논의하고자 한다. 역할 기반 보안은 COM+ 서비스에서 제공해주는 여러 가지 강력한 기능들 가운데서도 개발자들에게 그다지 주목받지 못하고 있는 몇 가지 대표적인 기능들 중 하나다. 게다가 ASP 프로그램 개발자들 대부분이 애시당초 COM+ 서비스 자체를 사용하지 않고 있는 추세이므로 이러한 경향이 보다 심한 편이라고 얘기할 수 있을 것이다. 그러나, 비록 사용하고자 하는 컴포넌트가 COM+ 서비스에서 제공해주는 기능들을 전혀 감안하지 않고 개발되었다고 할지라도, COM+ 서비스에 등록해서 사용하는 것 자체만으로도 매우 큰 이점을 얻을 수 있는 경우가 가끔 있는데, 바로 ASP 프로그램에서 발생하는 컴포넌트의 권한 관련 오류를 해결하고자 할 때가 그 대표적인 사례라고 말할 수 있다.

가령, ASP 개발자들이 주로 방문하는 몇몇 유명 개발자 커뮤니티의 Q&A 게시판을 살펴보면 그다지 어렵지 않게 다음과 같은 내용의 질문들을 찾아볼 수 있다.

마이크로소프트 비주얼 베이직 6.0을 사용하여 레지스트리에서 데이터를 읽거나 쓰는 COM 컴포넌트를 개발했는데 ASP 프로그램에서 사용해보니 권한이 없다고 오류가 발생합니다.

또는...

윈도우즈 서비스를 제어하는 COM 컴포넌트를 만들었는데 윈도우즈 응용 프로그램에서는 아무런 문제없이 잘 동작하던 COM 컴포넌트가 ASP 프로그램에서는 오류를 발생시킵니다.

등의 경우가 바로 그것이다. 이런 문제점을 접하게 됐을 때 사용할 수 있는 일반적으로 알려진 해결 방법으로는 IIS의 설정에서 익명 사용자 계정을 충분한 권한을 가진 다른 윈도우즈 사용자 계정으로 변경하는 방법 등 몇 가지 방법이 존재하기는 하지만 대부분 그다지 깔끔하지 못하거나 특별한 조건을 만족하는 경우에만 사용할 수 있는 등, 근본적인 해결책을 제시해주지는 못한다. 더군다나 그 방법에 따라서는 커다란 보안상의 위협을 초래하게 되는 경우도 있다. 그러나, COM+ 서비스에서 제공해주는 역할 기반 보안을 사용하면 보안상의 위험을 최소화하고 모든 문제를 매우 쉽고 깔끔하게 해결할 수 있다. ASP 프로그램이나 컴포넌트의 코드를 수정해줄 필요도 없으며, 단지 구성 요소 서비스 스냅인을 사용해서 COM+ 서비스에 컴포넌트를 등록하고 몇 가지 설정을 해주는 것만으로도 우리가 필요로 하는 모든 작업이 마무리 된다.

먼저, 이런 문제점이 발생하게 되는 근본적인 원인부터 알아보자. IIS를 윈도우즈 시스템에 설치하면 특별한 목적을 위해서 마이크로소프트에서 미리 정의해 놓은 두 개의 윈도우즈 사용자 계정이 자동으로 만들어진다. IUSR_[MachineName] 계정과 IWAM_[MachineName] 계정이 바로 그것으로, 이 계정들의 이름에서 볼 수 있는 '[MachineName]'은 단어가 의미하는 바 그대로 현재 IIS가 설치된 서버의 NetBIOS 이름을 나타내는 것이다. 따라서, 만약 서버의 이름이 EGOCUBE라면 생성되는 계정은 IUSR_EGOCUBE와 IWAM_EGOCUBE가 된다. 이 두 계정 중에서 관심을 가져야 할 계정은 바로 IUSR_[MachineName] 계정이다. 또 다른 계정인 IWAM_[MachineName] 계정은 응용 프로그램 보호 항목이 보통(풀링됨)이나 높음(격리됨)으로 설정된 IIS 웹 응용 프로그램을 호스팅하는 COM+ 응용 프로그램의 DLLHOST.EXE 프로세스의 프로세스 ID로 사용되기 위한 계정으로, 이 계정에 대한 내용은 본문의 범위를 벗어날 뿐만 아니라 글의 진행에 하등 영향을 미치지 않으므로 이 자리에서는 더 이상 논의하지 않기로 하겠다.

그리고, IIS가 설치되고 난 뒤에 특별히 보안 관련 설정을 변경하지 않았다면 기본적으로 익명 엑세스가 허용되어 있는 상태일텐데, 이 상태에서는 브라우저로 웹 사이트에 접속하는 모든 사용자의 신원 계정은 IUSR_[MachineName] 계정이 된다. 결국, 이 얘기는 모든 사용자가 IUSR_[MachineName] 계정으로 해당 웹 사이트의 IIS가 운영되고 있는 윈도우즈 시스템에 로그인 한 것과 비슷한 상태가 된다는 말과 거의 같은 얘기다. 그러므로, 임의의 사용자가 브라우저로 웹 서버의 특정 리소스에 접근을 시도하는 경우, IUSR_[MachineName] 계정이 해당 리소스에 접근할 수 있는 권한을 갖고 있지 않다면 당연히 권한 관련 오류를 발생시키게 되고, 문제는 IUSR_[MachineName] 계정이 바로 Guests 그룹에 속한 계정이라는 사실이다. 따라서, 예로 들었던 레지스트리의 데이터를 읽거나 쓰는 컴포넌트, 또는 윈도우즈 서비스를 제어하는 컴포넌트가 올바르게 동작하지 않고 권한 관련 오류를 발생시키는 것은 너무나도 당연한 결과다. 왜냐하면 레지스트리의 데이터나 윈도우즈 서비스 같은 중요한 리소스들을 고작 Guests 그룹에 속해 있는 계정으로 접근할 수 있게 허용해 줄 수는 없는 노릇이니 말이다.

일반적인 경우를 가정할 때, 역할 기반 보안을 이용하는 방법을 고려하지 않고 생각해본다면 이런 문제점을 해결할 수 있는 방법이 두 세 가지 정도 존재한다. 첫 번째 방법은 그냥 단순하게 IUSR_[MachineName] 계정을 Administrators 그룹이나 또는 그에 준하는 적절한 권한을 갖고 있는 그룹의 멤버로 설정하는 것이다. 그러나, 이 방법은 거의 보안을 포기하는 것이나 마찮가지라고 말할 수 있다. 두 번째 방법은 IUSR_[MachineName] 계정으로 설정되어 있는 익명 사용자 계정 자체를 아예 적당한 다른 계정으로 교체하는 것이다. 다음 이미지에서 볼 수 있는 것처럼 인터넷 정보 서비스 스냅인에서 익명 사용자 계정의 설정을 변경하는 것이 가능한데, 그 방법 자체야 설명이 따로 필요없을 정도로 간단하지만 결국 이 방법도 첫 번째 방법과 마찮가지로 보안상의 심각한 문제가 발생하게 된다는 큰 단점이 존재한다.

'익명 사용자 계정' 대화 상자

마지막 세 번째 방법은 ASP 프로그래밍이나 설정상의 관점에서의 해결책이라기 보다는 사이트의 구조적인 컨셉 측면에서의 바라본 해결책이다. 즉, 적절한 권한이 요구되는 모든 ASP 프로그램들을 특정한 웹 디렉터리의 하위에 모두 위치시킨 다음, 해당 웹 디렉터리를 비롯해서 그 하위에 존재하는 모든 디렉터리들의 보안 설정에서 익명 엑세스를 해제하고 통합 인증을 사용하는 것이다. 일반적으로 대부분의 사이트들에 존재하는 관리자 페이지를 생각해보면 이해가 빠를 것이다. 그러나, 이 방법은 주변 여건이 허용되는 경우에만 적용이 가능하고 또한 이렇게 구분된 ASP 프로그램을 사용하는 모든 사용자들에게 적절한 권한을 가진 윈도우즈 사용자 계정을 생성해줘야만 한다는 단점이 존재한다. 결국 완벽한 해결책은 될 수 없는 것이다.

그러나, 역할 기반 보안을 사용하면 이런 문제점들을 더할 나위 없이 깔끔하게 해결하는 것이 가능해진다. 다만 한 가지 확실하게 얘기하고 넘어가야 할 부분이 있는데, 본래 역할 기반 보안은 지금과 같은 목적으로 사용하기 위해서 제공되는 기능이 절대 아니며 본문에서 설명하고 있는 내용들은 그 본래의 기능에서 얻어지는 부산물과 같은 이점이라는 사실이다. 간단하게 말해서 덤으로 얻어진 편리한 기능인 셈인데, 조금 더 자세하게 설명을 하자면 본문에서 다루고 있는 부분들은 역할 기반 보안을 사용하기 위한 기본적인 설정의 일부분 같은 것이라고 말할 수 있다. 역할 기반 보안을 사용하려면 우선 컴포넌트를 COM+ 서비스에 등록해줘야만 한다. 일단 컴포넌트가 COM+ 서비스에 등록되고 나면, 해당 컴포넌트는 인스턴스가 생성되는 시점에서부터 인스턴스가 제거되는 시점까지 언제나 COM+ 런타임의 제어를 받게 된다.

먼저 컴포넌트의 인스턴스 생성 과정에 관해서 중점적으로 논의해보도록 하겠다. ASP 프로그램이나 마이크로소프트 비주얼 베이직 6.0 또는 마이크로소프트 비주얼 C/C++ 6.0 등의 언어로 작성된 클라이언트 프로그램에서 컴포넌트의 인스턴스를 생성하려고 시도하면 COM+ 런타임이 내부적으로 이 과정 중에 개입하여 필요한 처리를 적절히 수행하고 처리 도중에 아무런 문제가 발생하지 않는다면 해당 컴포넌트의 인스턴스 참조를 리턴해준다. 비록 이처럼 간단하게 설명하기는 했지만 실제로 COM+ 런타임이 인스턴스를 생성하는 과정은 매우 복잡하며 이 글과 필자의 지식 수준을 가볍게 넘어서는 주제이므로 이 부분에 관해서는 더 이상 거론하지 않겠다. 다만 여기에서 우리가 깊게 관심을 가지고 생각해봐야 할 부분은 COM+ 런타임이 컴포넌트의 인스턴스를 생성하는 과정 중 해당 클라이언트 프로그램이, 아니 조금 더 정확하게 얘기하자면 해당 클라이언트 프로그램의 프로세스 ID가 컴포넌트의 인스턴스를 생성할 수 있는 충분한 권한을 갖고 있는지 여부를 COM+ 런타임이 확인하는 단계가 존재한다는 사실이다. 이 단계가 바로 인증(Authentication)이며, 인증에 실패하게 되면 당연히 컴포넌트의 인스턴스는 생성할 수가 없다.

그렇다면 결국 클라이언트 프로그램이 어떤 권한을 어떻게 얼마나 가지고 있는지가 문제의 관건이 된다. 클라이언트 프로그램이 일반적인 윈도우즈 응용 프로그램인 경우라면 현재 윈도우즈 시스템에 로그인해서 해당 응용 프로그램을 실행시킨 사용자 계정을 프로세스 ID로 갖게 되므로 권한 또한 그 사용자의 권한을 그대로 상속받는다. 따라서, 사용자에게 해당 컴포넌트의 인스턴스를 생성할 권한이 있다면 자연스럽게 클라이언트 프로그램도 그에 따라 컴포넌트의 인스턴스를 생성할 권한을 갖게 된다. 그러나, 클라이언트 프로그램이 ASP 프로그램이고 익명 엑세스가 허용되어 있는 일반적인 상황이라면 양상은 보다 복잡해진다. 이런 경우에는 방금 살펴봤던 IUSR_[MachineName] 계정이 ASP 프로그램의 프로세스 ID로 사용된다.

이번에는 생성된 컴포넌트의 인스턴스를 실제로 사용하는 과정에 관해서 중점적으로 살펴보자. 논의한 바와 같이 적절한 권한을 가진 사용자 계정으로 컴포넌트의 인스턴스를 생성하는데 성공했다면 역시 동일한 사용자 계정의 권한으로 컴포넌트가 실행되는 것일까? 결론부터 얘기하자면 경우에 따라서 그럴 수도 있고 아닐 수도 있다. 일단 COM+ 서비스에 등록되지 않은 컴포넌트의 경우에는 인스턴스를 생성하는 계정과 사용하는 계정이 동일하다. 예를 들어서 사용자가 Administrator 계정으로 로그인해서 윈도우즈 응용 프로그램을 실행시켰다면 Administrator 계정의 보안 문맥이 응용 프로그램과 그 응용 프로그램이 사용하는 모든 컴포넌트에 상속된다. 이는 지극히 당연한 얘기로 일반적인 윈도우즈 응용 프로그램들은 모두 이와 같은 환경에서 실행된다. ASP 프로그램의 경우도 역시 마찮가지라고 말할 수 있다. 다만 이 경우에는 특별히 설정을 변경하지 않았다면 계정 자체가 IUSR_[MachineName] 계정으로 미리 정해져 있다는 점만 다를 뿐이고, 그러므로 위에서 예로 든 레지스트리의 데이터를 읽고 쓰는 컴포넌트나 윈도우즈 서비스를 컨트롤하는 컴포넌트가 제대로 동작하지 않고 권한 관련 오류를 발생시키는 것이다. 즉, IUSR_[MachineName] 계정의 권한으로 컴포넌트의 인스턴스를 생성하는 단계까지는 성공했지만, 실행도 역시 IUSR_[MachineName] 계정의 권한을 사용하기 때문에 레지스트리나 윈도우즈 서비스에 접근하면서 Guests 그룹에 속한 계정인 IUSR_[MachineName] 계정의 보안 문맥이 거부되어 버린 것이다. 이 단계가 바로 권한(Authorization)이다.

그런데, COM+ 서비스에 등록된 컴포넌트의 경우에는 그 사정이 판이하게 달라진다. 역할 기반 보안의 뛰어난 점이 바로 이 부분인데 컴포넌트의 인스턴스를 생성할 수 있는 계정 자체를 설정해서 제한할 수도 있고, 컴포넌트의 모든 인터페이스에 존재하는 메서드들을 대상으로 각각 그 메서드를 사용할 수 있는 계정들을 별도로 제한하는 것도 가능하다. 그리고, 이 부분이 필자가 가장 말하고 싶었던 부분이기도 하고 본문의 핵심이기도 한데 컴포넌트의 인스턴스를 생성하는 계정과 컴포넌트를 사용하는 계정, 즉 컴포넌트의 프로세스 ID를 전혀 별개의 사용자 계정으로 각기 다르게 설정할 수 있다. 즉, 컴포넌트의 인스턴스를 생성하는 과정에서는 IUSR_[MachineName] 계정을 사용하지만 생성된 컴포넌트를 사용하는 계정은 Administrator 계정이 되도록 설정하는 것이 가능하다는 뜻이다. 따라서, ASP 프로그램에서 제한된 리소스에 대한 접근이 요구되는 컴포넌트를 사용할 때 발생하는 권한 문제를 간단하게 해결할 수 있다. 게다가 지금까지 운영해오던 웹 사이트의 구조를 수정할 필요도 없고 별도의 추가적인 코딩도 전혀 필요하지 않고 의도하지 않은 보안상의 취약점으로 불안을 느낄 필요도 없는 것이다.

방법 자체도 매우 간단한 편이다. 먼저 컴포넌트를 COM+ 서비스에 등록해야만 하므로 시작 메뉴나 제어판을 통해서 구성 요소 서비스 스냅인을 실행시킨다. 그리고, 구성 요소 서비스의 콘솔 트리를 살펴보면, 아래와 같이 COM+ 응용 프로그램 노드 하위에 존재하는, '+'로 표시가 되어 있는 구슬이 담긴 상자 모양의 아이콘들로 나타나는 하위 노드들을 볼 수 있을 것이다. 이 노드들을 COM+ 응용 프로그램이라고 하는데 과거 MTS 하에서 패키지라고 불렸던 바로 그것이다. 본문에서는 새로운 COM+ 응용 프로그램을 하나 만들어서 그곳에 컴포넌트를 등록하는 방법에 관해서 논의하도록 하겠다. 기존에 존재하고 있던 COM+ 응용 프로그램에 컴포넌트를 등록하는 것도 좋은 방법이지만 대부분 그런 COM+ 응용 프로그램들은 이미 각각의 목적에 맞는 상태로 설정되어져 있을 가능성이 높고, 또한 일부는 시스템과 관련된 COM+ 응용 프로그램이므로 괜히 건드려서 후회할 행동은 하지 않는 편이 좋다. 물론, 이는 COM+ 서비스에 능숙하신 분들에게는 해당 사항이 없는 얘기이긴 하지만 본문은 컴포넌트를 개발해서 ASP 프로그램에서 활용할 수 있는 능력은 갖고 있으나 아직까지 COM+ 서비스를 사용해본 경험은 그다지 많지 않은 분들을 대상으로 작성된 글이므로 각자 판단해서 적당한 방법을 선택한다.

구성 요소 서비스

먼저, 콘솔 트리에서 COM+ 응용 프로그램 노드를 마우스로 클릭해서 선택하고, 다시 마우스 오른쪽 버튼으로 클릭해서 팝업 메뉴를 띄운 다음, 새로 만들기응용 프로그램 메뉴을 차례대로 선택하여 실행시킨다. 이 경우, 반드시 COM+ 응용 프로그램 노드를 먼저 마우스로 선택하여 노드를 반전시키고 난 뒤에 팝업 메뉴를 띄워야만 새로 만들기 메뉴가 나타난다. 이런 특성은 MMC 프로그래밍 모델에 따른 것으로 오류라고는 얘기할 수 없는 것이다.

'새로 만들기 → 응용 프로그램' 메뉴

이제 새로 만들기응용 프로그램 메뉴를 실행하면 다음 이미지와 같이 COM 응용 프로그램 설치 마법사가 실행된다. 이 페이지에는 그저 단순한 소개글만 존재할 뿐 실질적으로는 아무런 의미도 없으므로 다음 버튼을 눌러서 작업을 계속 진행한다.

COM 응용 프로그램 설치 마법사

완전히 새로운 COM+ 응용 프로그램을 만들어야 하므로 빈 응용 프로그램을 만듭니다(M).라는 설명 좌측에 위치한 빈 상자 그림의 버튼을 누른다. 이 버튼을 클릭하면 아무런 내용도 존재하지 않는 초기 상태의 새로운 COM+ 응용 프로그램을 생성할 수 있다.

새 응용 프로그램을 설치하거나 만들기

이제 COM+ 응용 프로그램의 이름을 입력하고 활성화 유형을 선택한다. 이 때 활성화 유형은 반드시 다음의 이미지에서와 같이 서버 응용 프로그램으로 선택해야만 한다. 서버 응용 프로그램과 라이브러리 응용 프로그램의 근본적인 차이점은 등록된 컴포넌트의 인스턴스가 생성되는 위치라고 말할 수 있다. 그렇지만 이런 차이점은 COM+ 서비스의 보다 본질적인 기술적 사항에 포함되는 내용으로, 이 글에서 더 이상 깊게 거론할 성질의 내용은 아니라고 생각하며 이 부분에 관해서는 차후 별도의 글을 준비하도록 하겠다. 단지 간단하게 결론만 얘기하고 넘어가면, 라이브러리 응용 프로그램의 경우에는 언제나 등록된 컴포넌트의 인스턴스가 클라이언트 프로그램의 프로세스 내부에 생성되므로 불필요한 마샬링 작업을 피할 수가 있으며, 그러므로 실행 속도 측면에서의 이점은 얻을 수 있지만 반대로 언제나 그렇듯이 컴포넌트에서 발생한 오류로 인해서 전체 클라이언트, 즉 이 경우엔 IIS 자체에까지 그 치명적인 영향을 미칠 수 있다는 단점을 가지고 있다. 더군다나 생성되는 컴포넌트의 인스턴스는 항상 클라이언트 프로그램의 보안 문맥을 상속받으므로 본문에서 구현하고자 하는 방법과는 대치되는 설정인 셈이다. 게다가 라이브러리 응용 프로그램은 원격 엑세스라던가 QC(Queued Component)와 같은 보다 진보적인 기능들을 지원하지 않는다. 따라서, 지금 같은 상황에서는 COM+ 응용 프로그램의 활성화 유형을 반드시 서버 응용 프로그램으로 설정해야만 한다.

빈 응용 프로그램 만들기

이제 응용 프로그램 ID 설정 페이지에서 이 COM+ 응용 프로그램에 등록된 컴포넌트들의 프로세스 ID로 사용될 윈도우즈 사용자 계정을 등록해준다. 이런 계정을 신원 계정이라고 하는데 이 COM+ 응용 프로그램에 등록된 컴포넌트들은 인스턴스를 생성하는 클라이언트 프로그램의 종류에 상관 없이 항상 신원 계정으로 등록된 윈도우즈 사용자 계정으로 실행된다.

여기에서 ASP 프로그램에서 사용할 컴포넌트는 절대로 신원 계정을 대화형 사용자 항목으로 지정하지 않는 편이 좋다. 대화형 사용자가 의미하는 바는 다음 이미지에서도 알 수 있는 것처럼 현재 로그인한 사용자를 의미하는 것이다. 그러나, 일반적으로 IDC 같은 곳에서 서비스되고 있는 웹 서버들은 대부분 어떠한 사용자의 계정으로도 로그인되지 않은채 운영되는 것이 일반적이다. 따라서, 이런 경우 신원 계정이 대화형 사용자로 지정된 COM+ 응용 프로그램에 등록된 컴포넌트의 인스턴스를 생성하려고 시도하는 ASP 프로그램이 있다면 그 어떤 사용자의 보안 문맥도 얻을 수 없을 것이고 따라서 오류가 발생하게 된다. 이런 특성에 관해서 보다 더 자세한 내용을 알고 싶다면 다음의 마이크로소프트 기술 자료를 참고하기 바란다.

그러나, 다음 이미지에서처럼 Administrator 등 실제로 사용자나 특정 서비스에 사용되는 계정을 신원 계정으로 직접 할당하는 것은 사실 권장되지 않는다. 만약, 제대로 된 서버 관리자라면 암호 정책을 수립했을 터이고, 그에 따라 모든 계정들의 암호가 일정한 주기마다 변경될 것이다. 따라서, 이렇게 특정 계정을 바로 설정하면 암호 변경 주기에 맞춰 COM+ 응용 프로그램에 설정된 계정들의 암호도 수정해줘야 한다. 그러므로, 가장 권장되는 방법은 여느 서비스를 설치할 때와 마찬가지로 적절한 권한을 할당한 전용 계정을 생성하고, 로컬 사용자 및 그룹 스냅인에서 암호 변경할 수 없음 옵션을 설정해서 그 계정을 할당하는 것이다. 다만, 본문에서는 설명의 편의를 위해 일단 신원 계정에 Administrator 계정을 설정하기로 한다.

응용 프로그램 ID 설정

이제 다음 버튼을 누르면 다음 이미지와 같은 메세지가 나온다. 마지막으로 마침 버튼을 누르면 마법사가 종료되고 COM+ 응용 프로그램 설정이 완료된다.

COM+ 응용 프로그램 설정 완료

이제 새로운 COM+ 응용 프로그램이 성공적으로 생성되었으므로 필요한 컴포넌트를 등록할 수 있다. 다음과 같이 방금 생성한 COM+ 응용 프로그램의 하위 노드를 확장하여 구성 요소 노드를 선택한 다음, 마우스 오른쪽 버튼을 사용해서 팝업 메뉴를 띄운 후, 새로 만들기구성 요소 메뉴를 실행시킨다.

'새로 만들기 → 구성 요소' 메뉴

이렇게 새로 만들기구성 요소 메뉴를 실행시키면 다음 이미지와 같이 COM 구성 요소 설치 마법사가 나타난다. 이 페이지에는 단순한 소개글만 존재할 뿐 실질적인 의미는 없으므로 다음 버튼을 눌러서 작업을 계속 진행한다.

COM 구성 요소 설치 마법사

이제 구성 요소 가져오기 또는 설치 페이지에서 설치할 컴포넌트를 선택하면 된다. 본문에서는 설명의 편의를 위해 RegSvr32.exe나 자체 설치 프로그램으로 이미 설치된 COM 컴포넌트를 가져오는 경우를 예로 들어보도록 하겠다. 구성 요소 가져오기 또는 설치 페이지에는 다음 이미지와 같이 모두 세 개의 버튼이 존재하는데, 그 중 이미 등록된 구성 요소를 가져옵니다(M). 라는 설명의 좌측에 위치한 버튼을 누른다.

구성 요소 가져오기 또는 설치

그러면, 현재 시스템에 등록되어 있는 모든 컴포넌트들의 목록이 출력되는 리스트 박스가 나타나게 되는데, 이 리스트 박스에서 COM+ 응용 프로그램에 설치하고자 하는 컴포넌트들을 선택할 수 있다. 다음 이미지를 살펴보면 ASP 프로그램을 작성할 때 일반적으로 널리 사용되는 파일 업로드 컴포넌트인 ABCUpload 관련 컴포넌트들이 선택된 것을 볼 수 있는데 이처럼 업로드 관련 컴포넌트들을 COM+ 서비스에 등록해서 역할 기반 보안의 이점을 얻는 것도 좋은 활용 사례라고 말할 수 있다.

가져올 구성 요소 선택

일반적으로 악의적인 의도를 가진 사용자들이 ASP 프로그램으로 구축된 웹 사이트의 해킹을 시도하는 대부분의 경우, 가장 첫 번째로 목표가 되는 부분이 IIS 자체가 가지고 있는 버그이고, 그 다음이 바로 파일의 업로드가 가능한 자료실인 경우가 많다. 예를 들어서, 악의적인 코드를 포함하고 있는 ASP 프로그램 파일이나 해킹을 위한 실행 파일을 자료실에 업로드 한 다음, 웹 사이트의 구조를 분석해서 인터넷 익스플로러에 URL을 직접 입력하여 업로드한 ASP 프로그램이나 실행 프로그램을 실행시켜버리는 것이다. 따라서, 자료실을 구축하는 경우 실제로 자료들이 저장되는 폴더나 가상 디렉터리에는 절대로 실행 권한이나 스크립트 실행 권한을 부여해서는 안된다. 이런 가상의 상황은 관리자나 ASP 프로그래머가 초보자인 경우 충분히 발생할 가능성이 존재하는 시나리오다. 반드시 업로드 되는 파일의 확장자를 점검하여 의심스럽다는 판단이 들면 업로드 자체를 금지시키고 폴더의 권한을 철저히 관리하여 미리 대비하기 바란다.

역할 기반 보안은 이런 상황에서도 뛰어난 해결책을 제시해 줄 수 있다. 먼저, 자료실의 자료들이 실제로 저장되는 폴더나 가상 디렉터리의 권한 설정에서 IUSR_[MachineName] 계정에는 그저 읽기 권한만을 부여해주고 Administrators 그룹에는 반대로 모든 권한을 부여해준다. 그리고, COM+ 서비스에 업로드 컴포넌트를 등록하고 COM+ 응용 프로그램의 신원 계정을 Administrators 그룹에 속해 있는 계정들 중에서 적당한 계정을 선택하여 지정해준다. 이렇게 되면 IUSR_[MachineName] 계정에는 자료가 저장되는 폴더나 가상 디렉터리에 대한 읽기 권한 밖에 없으므로 인터넷 익스플로러를 사용해서 웹 사이트에 접근하는 모든 사용자들은 어떠한 불법적인 작업도 실행할 수가 없게 되고, 반면 업로드 컴포넌트 그 자체는 Administrators 그룹의 보안 문맥으로 실행되므로 여전히 정상적인 작업이 가능하다. 간단하면서도 확실한 방법이 아닐 수 없다.

윈도우즈 NT 서버 4.0 SP3 시절부터 ASP 프로그래밍을 해오셨던 분들이라면 기억하고 계실지도 모르겠지만, 그 당시에는 요즘과 같은 다양한 업로드 컴포넌트가 존재하지 않았었기 때문에 대부분 UPLOAD.EXE라는 이름을 갖고 있는, 아마 필자의 기억으로는 ISAPI 필터 프로그램이었던 것으로 기억되는데, 프로그램을 사용하여 자료실을 구축하는 것이 일반적이었다. 한 번에 약 3M 이상은 업로드가 되지 않는다는 단점이 존재하기는 했지만 당시로써는 발군의 그리고 개인적으로는 놀랍기만 했던 프로그램이었다. 그 당시 필자를 비롯한 초보자들이 자료실 구축 중 문제에 봉착해서 지금은 사라진 ASP Korea같은 커뮤니티 사이트에 그에 관련된 질문을 올리면 거의 언제나 'Everyone 계정에 모든 권한을 설정해보십시요.' 라는 답변이 올라오곤 했었다. 지금에 와서 생각해보면 위험천만한 해결 방법이 아닐 수 없다. 아직까지 UPLOAD.EXE로 운영되고 있는 자료실은 거의 극소수겠지만 만약 위와 같은 설정이 되어 있다면 앞에서 얘기했던 것과 같은 대비책들을 가급적 서둘러서 적용하는 것이 바람직할 것이다.

마지막으로 설치하고자 하는 컴포넌트들을 선택한 다음, 다음 버튼을 누르면 다음의 이미지와 같은 메세지가 출력되고, 다시 마침 버튼을 누르면 마법사가 종료되고 COM 구성 요소 설치가 완료된다.

구성 요소 설치 완료

다음 이미지는 컴포넌트 등록 절차가 모두 완료된 상태의 모습으로, 이미지가 희미해서 글씨가 잘 보이지는 않지만 모두 네 개의 컴포넌트가 등록되어 있는 것을 확인할 수 있을 것이다.

마지막으로 한 가지 반드시 짚고 넘어가야 할 부분이 있다. COM+ 서비스에 익숙하지 않으신 분들은 혹시 이런 의문을 가질 수도 있을 것이다.

구성 요소 서비스 스냅인으로 이렇게 아무 컴포넌트나 마음대로 등록해도 문제가 없을까? 나는 이 컴포넌트를 개발할 때 COM+ 서비스를 전혀 고려하지 않았는데 혹시 뭔가 잘못되는 것은 아닐까?

개발자라면 당연히 누구나 한 번쯤은 이런 의문이 생길 것이다. 게다가 이 의문은 실제로도 매우 중요한 문제로서 'COM+ 서비스에 등록된 컴포넌트의 실행 속도'같은 기타 성능상의 이슈들을 논외로 친다고 하더라도 경우에 따라서는 실제 서비스 운영시 치명적인 데이터 손실을 유발생시킬 수 있는 미묘한 문제이다. 즉, 지금까지 본문에서는 COM 컴포넌트와 COM+ 컴포넌트를 굳이 구분하여 설명하지 않았지만 이는 진행의 편의를 위해서 그런 것이고, 사실 어떤 측면에서 본다면 COM 컴포넌트와 COM+ 컴포넌트는 전혀 다른 종류의 컴포넌트라고 말할 수 있을 정도다. 물론, 윈도우즈 2000 이상의 COM+ 런타임 자체는 기존의 COM 런타임, 그리고 MTS Executive를 모두 포용하고 있기는 하지만 역시 이와 같은 사실도 '컴포넌트가 COM+ 서비스의 특성을 고려하여 제작되었는가?'라는 질문과는 논점 자체가 전혀 다르다. 따라서, COM+ 서비스를 전혀 고려하지 않은채 개발된 일반적인 COM 컴포넌트를 무작정 COM+ 서비스에 등록하면 않된다는 것은 너무나도 당연한 결론일 것이다.

그러나, 한 가지 다행스러운 사실은 이 문제를 해결하는데 있어서 주의해야 할 사항이 일단 두 가지 뿐이며, 더군다나 이 해결 방법이라는 것이 이미 위에서 말한 것처럼 코드를 수정한다든가 하는 번거로운 방법이 아니라 어디까지나 설정만으로 간단하게 해결이 가능한 고무적인 상황이라는 점이다. 비록 서론은 길었지만 논점은 간단한데, 다음 이미지처럼 적시 활성화(Just-In Time Activation)와 개체 풀링(Object Pooling)을 사용하지 않으면 된다. 그러나, 이에 대한 구체적인 의미를 설명하는 것은 이 글의 범위를 벗어나는 것이므로 더 이상 이 주제에 관해서 깊게 거론하지는 않겠다. COM+ 서비스에 등록된 임의의 컴포넌트를 마우스로 선택하고 팝업 메뉴를 띄워서 등록 정보 메뉴를 실행시키면 다음과 같이 해당 컴포넌트의 등록 정보 대화 상자가 나타난다. 적시 활성화와 개체 풀링의 설정은 대화 상자의 활성화 탭에서 변경할 수 있다. 다시 한 번 강조하지만, COM+ 서비스를 고려하지 않은채 작성된 컴포넌트는 절대로 적시 활성화와 개체 풀링 기능을 사용하면 않된다. 반드시 해당 항목의 체크 박스를 해제하도록 한다.

'새로 만들기 → 구성 요소' 메뉴

비록 필자의 글솜씨가 부족한 탓에 내용이 다소 길었졌지만, 결국 본문의 모든 설명은 '컴포넌트를 적절한 권한을 가진 계정으로 신원 계정이 할당된 COM+ 응용 프로그램에 등록해서 사용한다.' 정도로 요약할 수 있을 것이다. 그리고, 그 이유는 컴포넌트의 프로세스 ID를 적절한 권한을 갖고 있는 계정으로 설정하기 위한 것이다. 그렇다면 컴포넌트의 인스턴스를 생성할 수 있는 계정에 대한 설정은 어떻게 하는 것이 좋을까? 이 질문에 대해서 역할 기반 보안이라는 논제 자체에 충실한 답을 얻으려면 그것만으로도 COM+ 서적의 한 챕터를 상회할만한 분량의 글이 필요할 것이다. 그러나, 본문의 주제 자체에만 충실한 정답은 '현재 설정을 변경하지 않고 그대로 사용한다.'이다. 왜냐하면 COM+ 응용 프로그램은 기본적으로 IUSR_[MachineName] 계정을 비롯한 모든 계정들이 등록된 컴포넌트의 인스턴스를 생성할 수 있도록 설정되어 있기 때문이다.