Share via


URL 다시 쓰기 모듈에 대한 규칙 템플릿 개발

루슬란 야쿠셰프

이 연습에서는 URL 다시 쓰기 모듈에 대한 규칙 템플릿을 개발하는 방법을 안내합니다. 웹 사이트에 특정 도메인의 사용을 적용하는 다시 쓰기 규칙을 생성하는 데 사용할 수 있는 규칙 템플릿을 만듭니다.

템플릿 개요

정식 도메인 이름 규칙 템플릿을 사용하여 웹 사이트에 정식 도메인 이름을 적용하는 데 사용되는 재작성 규칙 만들기를 간소화할 수 있습니다. 사용자는 "규칙 추가" 대화 상자에서 이 템플릿을 선택할 수 있습니다.

그런 다음 사용자가 사용하려는 도메인 이름을 제공할 수 있습니다.

정식 도메인 이름 대화 상자에 지정된

그런 다음 템플릿은 다음과 같이 다시 쓰기 규칙을 생성합니다.

도메인 이름, URL, 조건 및 작업에 대한 섹션이 있는 규칙 편집 창의 스크린샷

사전 요구 사항

이 연습을 진행하기 전에 "간단한 IIS Manager 모듈을 만드는 방법" 문서의 작업을 완료하여 IIS Manager 확장성의 기본 개념을 숙지하는 것이 좋습니다.

규칙 템플릿에 대한 VS2008 프로젝트

이 규칙 템플릿에 대한 전체 Visual Studio 2008 프로젝트는 여기에서 다운로드할 수 있습니다.

규칙 템플릿 구현

원격 관리를 지원하기 위해 모든 IIS 관리자 UI 구성 요소는 특정 디자인 패턴을 따라 구현됩니다. 모듈의 구현은 다음 부분으로 구성됩니다.

  • 클라이언트 쪽 사용자 인터페이스 및 서비스 프록시
  • IIS 구성을 관리하기 위한 서버 쪽 서비스

모든 사용자 인터페이스 특정 구현은 원격 클라이언트 컴퓨터일 수 있는 클라이언트 쪽에 상주합니다. 실제로 IIS 구성을 변경하는 모든 기능은 서버 쪽에서 서비스로 구현되므로 모든 서버 구성 API에 액세스할 수 있습니다. 클라이언트 쪽 컨트롤은 서비스 프록시를 통해 서비스와 상호 작용합니다.

사용자가 IIS 원격 관리자를 통해 규칙을 만들 때 템플릿이 작동하도록 동일한 패턴을 따라 규칙 템플릿을 구현하는 것이 좋습니다. 다음 섹션에서는 규칙 템플릿 서비스 및 클라이언트를 구현하는 방법을 설명합니다.

클라이언트 쪽 사용자 인터페이스 구현

모듈 만들기

먼저 모듈을 만들어야 합니다. 는 모든 확장성 개체에 대한 클라이언트의 기본 진입점입니다. 이러한 작업을 하려면 다음을 수행합니다.

  1. "간단한 IIS 관리자 모듈을 만드는 방법" 문서의 작업 1과 2에 설명된 단계에 따라 Visual Studio 프로젝트를 만들고 구성합니다. 프로젝트의 이름을 "CanonicalDomainTemplateClient"로 지정합니다.
  2. 프로젝트 메뉴에서 참조 추가를 선택하고 \Windows\System32\inetsrv에 있는 Microsoft.Web.Management.dll 대한 참조를 추가합니다.
  3. 참조 추가를 다시 선택하고 \Program Files\Reference Assemblies\Microsoft\IIS에 있는 Microsoft.Web.Management.Rewrite.Client.dll 대한 참조를 추가합니다.
  4. 참조 추가를 다시 선택하고 System.Windows.Forms.dll 참조 추가
  5. 프로젝트 메뉴에서 새 항목 추가 옵션을 선택합니다. 새 항목 추가 대화 상자에서 클래스 템플릿을 선택하고 CanonicalDomainModule.cs를 파일 이름으로 입력합니다.
  6. 아래와 같이 표시되도록 코드를 변경합니다.
using System;
using Microsoft.Web.Management.Server;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Iis.Rewrite;

namespace CanonicalDomainTemplate
{
    internal class CanonicalDomainModule: Module
    {
        protected override void Initialize(IServiceProvider serviceProvider, ModuleInfo moduleInfo)
        {
            base.Initialize(serviceProvider, moduleInfo);

            IExtensibilityManager extensibilityManager = (IExtensibilityManager)GetService(typeof(IExtensibilityManager));

            extensibilityManager.RegisterExtension(typeof(RewriteTemplateFeature), new CanonicalDomainFeature(this)); 
        }
    }
}

이 코드는 규칙 템플릿 기능을 구현하는 CanonicalDomainFeature 클래스의 새 instance 초기화합니다. 이 클래스의 instance 모든 규칙 템플릿이 파생되는 형식인 RewriteTemplateFeature 형식의 확장을 등록하는 데 사용됩니다.

템플릿 다시 쓰기 기능 만들기

규칙 템플릿을 구현하는 클래스를 정의할 때 RewriteTemplateFeature 클래스에서 이 클래스를 파생시켜야 합니다. 모든 URL 다시 쓰기 규칙 템플릿에서 사용되는 부모 클래스입니다.

  1. 프로젝트 메뉴에서 새 항목 추가 옵션을 선택합니다. 클래스 템플릿을 선택하고 CanonicalDomainFeature.cs를 파일 이름으로 입력합니다.
  2. 아래와 같이 표시되도록 코드를 변경합니다.
using System;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Iis.Rewrite;
using System.Windows.Forms;
using System.Collections;

namespace CanonicalDomainTemplate
{
    class CanonicalDomainFeature: RewriteTemplateFeature
    {
        private const string FeatureTitle = "Canonical Domain Name";
        private const string FeatureDescription = "Creates a rewrite rule for enforcing canonical domain name for your web site";

        public CanonicalDomainFeature(Module module)
            : base(module, FeatureTitle, FeatureDescription, Resource.domain_icon16, Resource.domain_icon32)
        {
        }

        public override void Run()
        {
            CanonicalDomainModuleServiceProxy serviceProxy = 
                 (CanonicalDomainModuleServiceProxy)Connection.CreateProxy(this.Module, 
                                                                           typeof(CanonicalDomainModuleServiceProxy));
            CanonicalDomainForm form = new CanonicalDomainForm(serviceProxy);
            form.StartPosition = FormStartPosition.CenterParent;
            if (form.ShowDialog() == DialogResult.OK)
            {
                Navigate(GetPageType("Rewrite"));
            }
        }

        /// <summary>
        /// Returns the main page for the specified module
        /// </summary>
        private Type GetPageType(string moduleName)
        {
            IControlPanel controlPanel = (IControlPanel)GetService(typeof(IControlPanel));
            Module module = (Module)Connection.Modules[moduleName];

            if (module != null)
            {
                ICollection pageInfos = controlPanel.GetPages(module);

                foreach (ModulePageInfo pageInfo in pageInfos)
                {
                    if (pageInfo.IsEnabled && !pageInfo.PageType.IsAssignableFrom(typeof(IModuleChildPage)))
                    {
                        return pageInfo.PageType;
                    }
                }
            }

            return null;
        }
    }
}

이 코드는 다음을 수행합니다.

  1. 규칙 템플릿의 이름과 제목을 정의합니다.
  2. "규칙 추가" 대화 상자에 등록된 모든 규칙 템플릿이 표시될 때 사용할 수 있도록 이름, 제목 및 아이콘을 기본 클래스 생성자에 전달합니다.
  3. 템플릿 사용자 인터페이스(WinForm 기반 모달 대화 상자 CanonicalDomainForm)를 렌더링하는 데 사용되는 Run() 메서드를 정의합니다. 대화 상자에서 확인 단추를 클릭하면 URL 다시 쓰기 모듈의 기본 UI 페이지가 Navigate() 메서드를 호출하여 새로 고쳐집니다.
  4. 마지막으로 지정된 모듈의 기본 페이지를 가져오는 데 사용되는 도우미 함수 GetPageType을 정의합니다.

서비스 프록시 정의

원격 클라이언트가 서비스를 호출하려면 서비스 프록시를 제공해야 합니다. 이렇게 하려면 CanonicalDomainModuleServiceProxy.cs라는 다른 파일을 프로젝트에 추가하고 아래와 같이 코드를 변경합니다.

using System;
using Microsoft.Web.Management.Client;
using Microsoft.Web.Management.Server;

namespace CanonicalDomainTemplate
{
    class CanonicalDomainModuleServiceProxy : ModuleServiceProxy
    {

        public void GenerateRule(string domainName)
        {
            Invoke("GenerateRule", domainName);
        }
    }
}

GenerateRule 메서드에 대한 실제 서비스 구현은 나중에 추가됩니다.

규칙 템플릿 구현 대화 상자

이제 모든 IIS Manager 클라이언트 쪽 배관 코드가 완료되었으므로 나머지 부분은 규칙 템플릿에 대한 실제 사용자 인터페이스를 디자인하고 구현하는 것입니다. 이렇게 하려면 다음 단계를 수행합니다.

  1. 프로젝트 메뉴에서 새 항목 추가 옵션을 선택합니다. 새 항목 추가 대화 상자에서 "Windows Form"을 선택하고 CanonicalDomainForm.cs라는 이름을 입력합니다.
    Windows 양식 서식 파일이 선택된 새 항목 추가 대화 상자의 스크린샷

  2. Visual Studio Windows Forms 디자이너를 사용하여 양식에 대한 컨트롤을 정렬합니다.
    Visual Studio 창 양식 디자이너의 새 양식 스크린샷

  3. 코드 보기로 전환하고 서비스 프록시에 대한 참조를 포함할 클래스의 프라이빗 멤버를 추가합니다.

    private CanonicalDomainModuleServiceProxy _serviceProxy;
    
  4. 동일한 클래스에서 아래와 같이 생성자 코드를 수정합니다.

    public CanonicalDomainForm(CanonicalDomainModuleServiceProxy serviceProxy)
    {
       _serviceProxy = serviceProxy;
       InitializeComponent();
    }
    
  5. 동일한 클래스에서 서비스 프록시를 호출하여 사용자가 지정한 매개 변수를 사용하여 다시 쓰기 규칙을 생성하는 도우미 함수를 추가합니다.

    private void GenerateRule(string domainName)
    {
        try
        {
            _serviceProxy.GenerateRule(domainName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
  6. 확인 단추를 클릭할 때 에 대한 이벤트 처리기를 추가합니다. 이벤트 처리기 코드에서 도우미 함수 GenerateRule을 호출하여 TextBox 컨트롤의 콘텐츠를 매개 변수로 전달합니다.

    private void OnOkButtonClick(object sender, EventArgs e)
    {
        GenerateRule(_DomainTextBox.Text);
    }
    

규칙 템플릿에 대한 서비스 구현

서비스를 구현하려면 IIS 관리자에서 모듈 등록을 위한 진입점인 모듈 공급자를 만들어야 합니다. 이러한 작업을 하려면 다음을 수행합니다.

  1. "간단한 IIS 관리자 모듈을 만드는 방법" 문서의 작업 1과 2에 설명된 단계에 따라 다른 Visual Studio 프로젝트를 만들고 구성합니다. 프로젝트의 이름을 "CanonicalDomainTemplate"으로 지정합니다.

  2. 프로젝트 메뉴에서 참조 추가를 선택하고 \Windows\System32\inetsrv에 있는 다음 어셈블리에 대한 참조를 추가합니다.

    1. Microsoft.Web.Administration.dll
    2. Microsoft.Web.Management.dll
  3. 프로젝트 메뉴에서 새 항목 추가 옵션을 선택합니다. 새 항목 추가 대화 상자에서 클래스 템플릿을 선택하고 CanonicalDomainModuleProvider.cs를 파일 이름으로 입력합니다.

  4. 아래와 같이 표시되도록 코드를 변경합니다(PublicKeyToken을 CanonicalDomainTemplate.Client.dll 어셈블리의 공개 키 토큰으로 바꾸는 것을 잊지 마세요).

namespace CanonicalDomainTemplate
{
    internal sealed class CanonicalDomainModuleProvider : ModuleProvider
    {
        public override string FriendlyName
        {
            get
            {
                return Resource.ModuleFriendlyName;
            }
        }

        public override Type ServiceType
        {
            get {
                 return typeof(CanonicalDomainModuleService);
            }
        }

        public override ModuleDefinition GetModuleDefinition(IManagementContext context)
        {
            if (context != null && string.Compare(context.ClientUserInterfaceTechnology, 
            "System.Windows.Forms.Control", StringComparison.OrdinalIgnoreCase) != 0)
            {
                return null;
            }

            return new ModuleDefinition(Name, "CanonicalDomainTemplate.CanonicalDomainModule,
                                               CanonicalDomainTemplate.Client,Version=1.0.0.0,Culture=neutral,
                                               PublicKeyToken={your key}");
        }

        public override bool SupportsScope(ManagementScope scope)
        {
            return true;
        }
    }
}

이 코드는 모든 유형의 연결(서버, 사이트 및 애플리케이션)을 지원하는 ModuleProvider를 만들고 CanonicalDomainModule이라는 클라이언트 쪽 모듈을 등록합니다. 또한 서버 쪽에서 다시 쓰기 규칙을 생성하는 데 사용되는 모듈 서비스 CanonicalDomainModuleService 의 형식을 등록합니다.

규칙 템플릿에 대한 서비스를 만들려면 다음 단계를 수행합니다.

  1. 프로젝트 메뉴에서 새 항목 추가 옵션을 선택합니다. 클래스 템플릿을 선택하고 CanonicalDomainModuleService.cs를 파일 이름으로 입력합니다.
  2. 아래와 같이 표시되도록 코드를 변경합니다.
using System;
using System.Collections.Generic;
using Microsoft.Web.Management.Server;
using Microsoft.Web.Administration;

namespace CanonicalDomainTemplate
{
    class CanonicalDomainModuleService : ModuleService
    {

        [ModuleServiceMethod]
        public void GenerateRule(string domainName)
        {
            string sectionPath = "system.webServer/rewrite/rules";
            
            if (ManagementUnit.ConfigurationPath.PathType == ConfigurationPathType.Server)
            {
                sectionPath = "system.webServer/rewrite/globalRules";
            }

            ConfigurationSection rulesSection = ManagementUnit.Configuration.GetSection(sectionPath);
            ConfigurationElementCollection rulesCollection = rulesSection.GetCollection();

            ConfigurationElement ruleElement = rulesCollection.CreateElement("rule");
            ruleElement["name"] = @"Canonical domain for " + domainName;
            ruleElement["patternSyntax"] = @"Wildcard";
            ruleElement["stopProcessing"] = true;

            ConfigurationElement matchElement = ruleElement.GetChildElement("match");
            matchElement["url"] = @"*";

            ConfigurationElement conditionsElement = ruleElement.GetChildElement("conditions");

            ConfigurationElementCollection conditionsCollection = conditionsElement.GetCollection();

            ConfigurationElement addElement = conditionsCollection.CreateElement("add");
            addElement["input"] = @"{HTTP_HOST}";
            addElement["negate"] = true;
            addElement["pattern"] = domainName;
            conditionsCollection.Add(addElement);

            ConfigurationElement actionElement = ruleElement.GetChildElement("action");
            actionElement["type"] = @"Redirect";
            actionElement["url"] = @"http://" + domainName + @"/{R:1}";
            actionElement["appendQueryString"] = true;
            rulesCollection.Add(ruleElement);

            ManagementUnit.Update();
        }
    }
}

이 코드는 정식 도메인으로 리디렉션하는 규칙을 만듭니다.

다시 쓰기 규칙을 생성하는 코드를 빠르게 얻으려면 IIS용 관리 팩에 포함된 IIS 7.0 이상의 구성 편집기를 사용합니다. 다시 쓰기 규칙을 만들기 위한 코드를 생성하는 방법에 대한 자세한 내용은 이 문서를 참조하세요.

IIS 관리자에 규칙 템플릿 등록

규칙 템플릿 프로젝트가 성공적으로 컴파일되어 전역 어셈블리 캐시에 배치되면 해당 정보를 administration.config 파일에 추가하여 IIS Manager에 등록해야 합니다.

\Windows\System32\inetsrv\config에 있는 administration.config 파일을 열고 moduleProviders> 섹션에 <다음 줄을 추가합니다. PublicKeyToken을 바꿔야 합니다.

<add name="CanonicalDomainName" type="CanonicalDomainTemplate.CanonicalDomainModuleProvider, CanonicalDomainTemplate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e4e6d0bc8fe7a06a" />

참고

moduleProviders 목록에만 추가하면 서버 연결에 대해서만 모듈을 등록합니다. 이 모듈을 사이트 연결 및 애플리케이션 연결에 사용하도록 설정하려면 다음 목록에 추가합니다.

<location path=".">
   <module> 
     <add name="CanonicalDomainName" />
   </module>
</location>

이러한 단계가 완료되면 URL 다시 쓰기 모듈의 규칙 추가 대화 상자에서 "정식 도메인 이름" 규칙 템플릿을 볼 수 있습니다.