Windows Server에서 AD FS에 대한 사용자 지정 인증 방법 빌드

이 연습에서는 Windows Server 2012 R2에서 AD FS에 대한 사용자 지정 인증 방법을 구현하기 위한 지침을 제공합니다. 자세한 내용은 추가 인증 방법을 참조 하세요.

Warning

여기서 빌드할 수 있는 예제는 교육용으로만 사용됩니다.  이러한 지침은 모델의 필수 요소를 노출할 수 가장 간단 하 고 가장 최소한의 구현에 대 한 것입니다.  인증 백 엔드, 오류 처리 또는 구성 데이터가 없습니다.

개발 상자를 설정합니다.

이 연습에서는 Visual Studio 2012를 사용합니다. Windows용 .NET 클래스를 만들 수 있는 모든 개발 환경을 사용하여 프로젝트를 빌드할 수 있습니다. BeginAuthentication 및 TryEndAuthentication 메서드는 .NET Framework 버전 4.5의 일부인 System.Security.Claims.Claim 형식을 사용하므로 프로젝트는 .NET 4.5를 대상으로 해야 합니다. 프로젝트에는 다음 참조가 필요합니다.

참조 dll 찾을 위치 필수
Microsoft.IdentityServer.Web.dll dll은 AD FS가 설치된 Windows Server 2012 R2 서버의 %windir%\ADFS에 있습니다.

이 dll은 개발 머신과 프로젝트에서 만든 명시적 참조로 복사해야 합니다.

IAuthenticationContext, IProofData를 포함한 인터페이스 형식

공급자 만들기

  1. Visual Studio 2012: 파일->새로 만들기->프로젝트 선택...

  2. 클래스 라이브러리를 선택하고 .NET 4.5를 대상으로 지정해야 합니다.

    Screenshot of the New Project dialog box showing the Class Library option selected.

  3. AD FS가 설치된 Windows Server 2012 R2 서버의 %windir%\ADFS에서 Microsoft.IdentityServer.Web.dll 의 복사본을 만들고 개발 컴퓨터의 Project 폴더에 붙여넣습니다.

  4. 솔루션 탐색기 참조를마우스 오른쪽 단추로 클릭하고 참조 추가...

  5. Microsoft.IdentityServer.Web.dll추가...의 로컬 복사본으로 이동합니다.

  6. 확인을 클릭하여 새 참조를 확인합니다.

    Screenshot of the Reference Manager dialog box showing the Microsoft.IdentityServer.Web.dll selected.

    이제 공급자에 필요한 모든 형식을 확인하도록 설정해야 합니다.

  7. 프로젝트에 새 클래스 추가(프로젝트를 마우스 오른쪽 단추로 클릭하고 추가... 클래스...) 아래에 표시된 MyAdapter와 같은 이름을 지정합니다.

    Screenshot of the Add New Item dialog box with the Class option selected.

  8. 새 파일 MyAdapter.cs에서 기존 코드를 다음으로 바꿉니다.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Globalization;
    using System.IO;
    using System.Net;
    using System.Xml.Serialization;
    using Microsoft.IdentityServer.Web.Authentication.External;
    using Claim = System.Security.Claims.Claim;
    
    namespace MFAadapter
    {
        class MyAdapter : IAuthenticationAdapter
        {
            public IAuthenticationAdapterMetadata Metadata
            {
                //get { return new <instance of IAuthenticationAdapterMetadata derived class>; }
            }
    
            public IAdapterPresentation BeginAuthentication(Claim identityClaim, HttpListenerRequest request, IAuthenticationContext authContext)
            {
                //return new instance of IAdapterPresentationForm derived class
            }
    
            public bool IsAvailableForUser(Claim identityClaim, IAuthenticationContext authContext)
            {
                return true; //its all available for now
            }
    
            public void OnAuthenticationPipelineLoad(IAuthenticationMethodConfigData configData)
            {
                //this is where AD FS passes us the config data, if such data was supplied at registration of the adapter
            }
    
            public void OnAuthenticationPipelineUnload()
            {
    
            }
    
            public IAdapterPresentation OnError(HttpListenerRequest request, ExternalAuthenticationException ex)
            {
                //return new instance of IAdapterPresentationForm derived class
            }
    
            public IAdapterPresentation TryEndAuthentication(IAuthenticationContext authContext, IProofData proofData, HttpListenerRequest request, out Claim[] outgoingClaims)
            {
                //return new instance of IAdapterPresentationForm derived class
            }
    
        }
    }
    
  9. 아직 빌드할 준비가 되지 않았습니다... 두 가지 인터페이스가 더 있습니다.

    프로젝트에 두 개의 클래스를 더 추가합니다. 하나는 메타데이터용이고 다른 하나는 프레젠테이션 양식용입니다. 위의 클래스와 동일한 파일 내에 추가할 수 있습니다.

    class MyMetadata : IAuthenticationAdapterMetadata
    {
    
    }
    
    class MyPresentationForm : IAdapterPresentationForm
    {
    
    }
    
  10. 다음으로 각각에 필요한 멤버를 추가할 수 있습니다. 첫째, 메타데이터(유용한 기능줄 주석s)

    class MyMetadata : IAuthenticationAdapterMetadata
    {
        //Returns the name of the provider that will be shown in the AD FS management UI (not visible to end users)
        public string AdminName
        {
            get { return "My Example MFA Adapter"; }
        }
    
        //Returns an array of strings containing URIs indicating the set of authentication methods implemented by the adapter 
        /// AD FS requires that, if authentication is successful, the method actually employed will be returned by the
        /// final call to TryEndAuthentication(). If no authentication method is returned, or the method returned is not
        /// one of the methods listed in this property, the authentication attempt will fail.
        public virtual string[] AuthenticationMethods 
        {
            get { return new[] { "http://example.com/myauthenticationmethod1", "http://example.com/myauthenticationmethod2" }; }
        }
    
        /// Returns an array indicating which languages are supported by the provider. AD FS uses this information
        /// to determine the best language\locale to display to the user.
        public int[] AvailableLcids
        {
            get
            {
                return new[] { new CultureInfo("en-us").LCID, new CultureInfo("fr").LCID};
            }
        }
    
        /// Returns a Dictionary containing the set of localized friendly names of the provider, indexed by lcid. 
        /// These Friendly Names are displayed in the "choice page" offered to the user when there is more than 
        /// one secondary authentication provider available.
        public Dictionary<int, string> FriendlyNames
        {
            get
            {
                Dictionary<int, string> _friendlyNames = new Dictionary<int, string>();
                _friendlyNames.Add(new CultureInfo("en-us").LCID, "Friendly name of My Example MFA Adapter for end users (en)");
                _friendlyNames.Add(new CultureInfo("fr").LCID, "Friendly name translated to fr locale");
                return _friendlyNames;
            }
        }
    
        /// Returns a Dictionary containing the set of localized descriptions (hover over help) of the provider, indexed by lcid. 
        /// These descriptions are displayed in the "choice page" offered to the user when there is more than one 
        /// secondary authentication provider available.
        public Dictionary<int, string> Descriptions
        {
            get 
            {
                Dictionary<int, string> _descriptions = new Dictionary<int, string>();
                _descriptions.Add(new CultureInfo("en-us").LCID, "Description of My Example MFA Adapter for end users (en)");
                _descriptions.Add(new CultureInfo("fr").LCID, "Description translated to fr locale");
                return _descriptions; 
            }
        }
    
        /// Returns an array indicating the type of claim that the adapter uses to identify the user being authenticated.
        /// Note that although the property is an array, only the first element is currently used.
        /// MUST BE ONE OF THE FOLLOWING
        /// "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"
        /// "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"
        /// "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
        /// "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid"
        public string[] IdentityClaims
        {
            get { return new[] { "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" }; }
        }
    
        //All external providers must return a value of "true" for this property.
        public bool RequiresIdentity
        {
            get { return true; }
        }
    }
    

    이제 IAuthenticationAdapter에서 F12(마우스 오른쪽 단추 클릭 – 정의로 이동)하여 필요한 인터페이스 멤버 집합을 볼 수 있습니다.

    다음으로 이러한 구현을 수행할 수 있습니다.

  11. 클래스의 전체 내용을 다음으로 바꿉니다.

    namespace MFAadapter
    {
        class MyAdapter : IAuthenticationAdapter
        {
            public IAuthenticationAdapterMetadata Metadata
            {
                //get { return new <instance of IAuthenticationAdapterMetadata derived class>; }
            }
    
            public IAdapterPresentation BeginAuthentication(Claim identityClaim, HttpListenerRequest request, IAuthenticationContext authContext)
            {
                //return new instance of IAdapterPresentationForm derived class
            }
    
            public bool IsAvailableForUser(Claim identityClaim, IAuthenticationContext authContext)
            {
                return true; //its all available for now
            }
    
            public void OnAuthenticationPipelineLoad(IAuthenticationMethodConfigData configData)
            {
                //this is where AD FS passes us the config data, if such data was supplied at registration of the adapter
            }
    
            public void OnAuthenticationPipelineUnload()
            {
    
            }
    
            public IAdapterPresentation OnError(HttpListenerRequest request, ExternalAuthenticationException ex)
            {
                //return new instance of IAdapterPresentationForm derived class
            }
    
            public IAdapterPresentation TryEndAuthentication(IAuthenticationContext authContext, IProofData proofData, HttpListenerRequest request, out Claim[] outgoingClaims)
            {
                //return new instance of IAdapterPresentationForm derived class
            }
        }
    }
    

    다음으로 프레젠테이션 양식은 다음과 같습니다.

    class MyPresentationForm : IAdapterPresentationForm
    {
        /// Returns the HTML Form fragment that contains the adapter user interface. This data will be included in the web page that is presented
        /// to the cient.
        public string GetFormHtml(int lcid)
        {
            string htmlTemplate = Resources.FormPageHtml; //todo we will implement this
            return htmlTemplate;
        }
    
        /// Return any external resources, ie references to libraries etc., that should be included in
        /// the HEAD section of the presentation form html.
        public string GetFormPreRenderHtml(int lcid)
        {
            return null;
        }
    
        //returns the title string for the web page which presents the HTML form content to the end user
        public string GetPageTitle(int lcid)
        {
            return "MFA Adapter";
        }
    }
    
  12. 위의 Resources.FormPageHtml 요소에 대한 'todo'를 확인합니다. 1분 안에 수정할 수 있지만, 먼저 새로 구현된 형식을 기반으로 하는 최종 필수 반환 문을 초기 MyAdapter 클래스에 추가해 보겠습니다. 이렇게 하려면 기존 IAuthenticationAdapter 구현에 다음을 추가합니다.

    class MyAdapter : IAuthenticationAdapter
    {
        public IAuthenticationAdapterMetadata Metadata
        {
            //get { return new <instance of IAuthenticationAdapterMetadata derived class>; }
            get { return new MyMetadata(); }
        }
    
        public IAdapterPresentation BeginAuthentication(Claim identityClaim, HttpListenerRequest request, IAuthenticationContext authContext)
        {
            //return new instance of IAdapterPresentationForm derived class
            return new MyPresentationForm();
        }
    
        public bool IsAvailableForUser(Claim identityClaim, IAuthenticationContext authContext)
        {
            return true; //its all available for now
        }
    
        public void OnAuthenticationPipelineLoad(IAuthenticationMethodConfigData configData)
        {
            //this is where AD FS passes us the config data, if such data was supplied at registration of the adapter
        }
    
        public void OnAuthenticationPipelineUnload()
        {
    
        }
    
        public IAdapterPresentation OnError(HttpListenerRequest request, ExternalAuthenticationException ex)
        {
            //return new instance of IAdapterPresentationForm derived class
            return new MyPresentationForm();
        }
    
        public IAdapterPresentation TryEndAuthentication(IAuthenticationContext authContext, IProofData proofData, HttpListenerRequest request, out Claim[] outgoingClaims)
        {
            //return new instance of IAdapterPresentationForm derived class
            outgoingClaims = new Claim[0];
            return new MyPresentationForm();
        }
    
    }
    
  13. 이제 html 조각이 포함된 리소스 파일의 경우 다음 내용을 사용하여 프로젝트 폴더에 새 텍스트 파일을 만듭니다.

    <div id="loginArea">
        <form method="post" id="loginForm" >
            <!-- These inputs are required by the presentation framework. Do not modify or remove -->
            <input id="authMethod" type="hidden" name="AuthMethod" value="%AuthMethod%" />
            <input id="context" type="hidden" name="Context" value="%Context%" />
            <!-- End inputs are required by the presentation framework. -->
            <p id="pageIntroductionText">This content is provided by the MFA sample adapter. Challenge inputs should be presented below.</p>
            <label for="challengeQuestionInput" class="block">Question text</label>
            <input id="challengeQuestionInput" name="ChallengeQuestionAnswer" type="text" value="" class="text" placeholder="Answer placeholder" />
            <div id="submissionArea" class="submitMargin">
                <input id="submitButton" type="submit" name="Submit" value="Submit" onclick="return AuthPage.submitAnswer()"/>
            </div>
        </form>
        <div id="intro" class="groupMargin">
            <p id="supportEmail">Support information</p>
        </div>
        <script type="text/javascript" language="JavaScript">
            //<![CDATA[
            function AuthPage() { }
            AuthPage.submitAnswer = function () { return true; };
            //]]>
        </script>
    </div>
    
  14. 그런 다음, Project-Add> Component...를 선택합니다. 리소스 파일 및 파일 리소스 이름을 지정하고 추가를 클릭합니다.

    Screenshot of the Add New Item dialog box showing Resource File selected.

  15. 그런 다음 Resources.resx 파일 내에서 리소스 추가를 선택합니다. 기존 파일을 추가합니다. 위에 저장한 텍스트 파일(html 조각 포함)으로 이동합니다.

    GetFormHtml 코드가 리소스 파일(.resx 파일) 이름 접두사 뒤에 리소스 자체의 이름으로 새 리소스의 이름을 올바르게 확인하는지 확인합니다.

    public string GetFormHtml(int lcid)
    {
        string htmlTemplate = Resources.MfaFormHtml; //Resxfilename.resourcename
        return htmlTemplate;
    }
    

이제 빌드할 수 있습니다.

어댑터 빌드

어댑터는 Windows의 GAC에 설치할 수 있는 강력한 이름의 .NET 어셈블리에 빌드되어야 합니다. Visual Studio 프로젝트에서 이 작업을 수행하려면 다음 단계를 완료합니다.

  1. 솔루션 탐색기 프로젝트 이름을 마우스 오른쪽 단추로 클릭하고 속성을 클릭합니다.

  2. 서명 탭에서 검사 어셈블리에 서명하고 새로 만들기를 선택합니다<.> 강력한 이름 키 파일 선택: 키 파일 이름과 암호를 입력하고 확인을 클릭합니다. 그런 다음 어셈블리 서명이 검사 지연 기호만 해제되었는지 확인합니다검사. 속성 서명 페이지는 다음과 같습니다.

    build the provider

  3. 그런 다음 솔루션을 빌드합니다.

AD FS 테스트 머신에 어댑터 배포

AD FS에서 외부 공급자를 호출하려면 먼저 시스템에 등록해야 합니다. 어댑터 공급자는 GAC에서 설치를 포함하여 필요한 설치 작업을 수행하는 설치 관리자를 제공해야 하며 설치 관리자는 AD FS에서 등록을 지원해야 합니다. 이 작업이 수행되지 않으면 관리자는 아래의 Windows PowerShell 단계를 실행해야 합니다. 이러한 단계는 랩에서 테스트 및 디버깅을 사용하도록 설정하는 데 사용할 수 있습니다.

테스트 AD FS 컴퓨터 준비

파일을 복사하고 GAC에 추가합니다.

  1. Windows Server 2012 R2 컴퓨터 또는 가상 머신이 있는지 확인합니다.

  2. AD FS 역할 서비스를 설치하고 하나 이상의 노드가 있는 팜을 구성합니다.

    랩 환경에서 페더레이션 서버를 설정하는 자세한 단계는 Windows Server 2012 R2 AD FS 배포 가이드를 참조 하세요.

  3. Gacutil.exe 도구를 서버에 복사합니다.

    Gacutil.exe는 Windows 8 컴퓨터의 %homedrive%Program Files (x86)Microsoft SDKsWindowsv8.0AbinNETFX 4.0 Tools 에서 찾을 수 있습니다. NETFX 4.0 도구 위치 아래에 gacutil.exe 파일 자체와 1033, en-US 및 기타 지역화된 리소스 폴더가 필요합니다.

  4. 공급자 파일(하나 이상의 강력한 이름 서명된 .dll 파일)을 gacutil.exe동일한 폴더 위치에 복사합니다(위치는 편의를 위해 제공됨).

  5. 팜의 각 AD FS 페더레이션 서버에서 GAC에 .dll 파일을 추가합니다.

    예: 명령줄 도구 GACutil.exe를 사용하여 GAC에 dll을 추가합니다. C:>.gacutil.exe /if .<yourdllname>.dll

    GAC에서 결과 항목을 보려면 다음을 수행합니다.C:>.gacutil.exe /l <yourassemblyname>

AD FS에 공급자 등록

위의 필수 구성 요소가 충족되면 페더레이션 서버에서 Windows PowerShell 명령 창을 열고 다음 명령을 입력합니다(Windows 내부 데이터베이스 사용하는 페더레이션 서버 팜을 사용하는 경우 팜의 기본 페더레이션 서버에서 이러한 명령을 실행해야 합니다.)

  1. Register-AdfsAuthenticationProvider –TypeName YourTypeName –Name “AnyNameYouWish” [–ConfigurationFilePath (optional)]

    여기서 YourTypeName은 .NET 강력한 형식 이름입니다. "YourDefaultNamespace.YourIAuthenticationAdapterImplementationClassName, YourAssemblyName, Version=YourAssemblyVersion, Culture=neutral, PublicKeyToken=YourPublicKeyTokenValue, processorArchitecture=MSIL"

    그러면 외부 공급자를 AD FS에 등록하고 위에서 AnyNameYouWish로 제공한 이름을 사용합니다.

  2. AD FS 서비스를 다시 시작합니다(예: Windows 서비스 스냅인 사용).

  3. Get-AdfsAuthenticationProvider 명령을 실행합니다.

    그러면 공급자가 시스템의 공급자 중 하나로 표시됩니다.

    예시:

    $typeName = "MFAadapter.MyAdapter, MFAadapter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e675eb33c62805a0, processorArchitecture=MSIL”
    Register-AdfsAuthenticationProvider -TypeName $typeName -Name “MyMFAAdapter”
    net stop adfssrv
    net start adfssrv
    

    AD FS 환경에서 디바이스 등록 서비스를 사용하도록 설정한 경우 다음 PowerShell 명령도 실행합니다. net start drs

    등록된 공급자를 확인하려면 다음 PowerShell 명령을Get-AdfsAuthenticationProvider 사용합니다.

    그러면 공급자가 시스템의 공급자 중 하나로 표시됩니다.

어댑터를 호출하는 AD FS 인증 정책 만들기

AD FS 관리 스냅인을 사용하여 인증 정책 만들기

  1. 서버 관리자 도구 메뉴에서 AD FS 관리 스냅인을 엽니다.

  2. 인증 정책을 클릭합니다.

  3. 가운데 창의 Multi-Factor Authentication 아래에서 전역 설정 오른쪽에 있는 편집 링크를 클릭합니다.

  4. 페이지 아래쪽에 있는 추가 인증 방법 선택에서 공급자의 관리 이름 상자를 검사. 적용을 클릭합니다.

  5. 예를 들어 어댑터를 사용하여 MFA를 호출하는 "트리거"를 제공하려면 위치 검사 엑스트라넷인트라넷을 모두 제공합니다. 확인을 클릭합니다. (신뢰 당사자별로 트리거를 구성하려면 아래의 "Windows PowerShell을 사용하여 인증 정책 만들기"를 참조하세요.)

  6. 다음 명령을 사용하여 결과를 확인합니다.

    먼저 사용합니다 Get-AdfsGlobalAuthenticationPolicy. 공급자 이름이 AdditionalAuthenticationProvider 값 중 하나로 표시됩니다.

    그런 다음 Get-AdfsAdditionalAuthenticationRule을 사용합니다. 관리자 UI에서 정책 선택 결과로 구성된 엑스트라넷 및 인트라넷에 대한 규칙이 표시됩니다.

Windows PowerShell을 사용하여 인증 정책 만들기

  1. 먼저 전역 정책에서 공급자를 사용하도록 설정합니다.

    Set-AdfsGlobalAuthenticationPolicy -AdditionalAuthenticationProvider “YourAuthProviderName”`
    

    참고 항목

    AdditionalAuthenticationProvider 매개 변수에 제공된 값은 위의 Register-AdfsAuthenticationProvider cmdlet에서 "Name" 매개 변수에 대해 제공한 값과 Get-AdfsAuthenticationProvider cmdlet 출력의 "Name" 속성에 해당합니다.

    Set-AdfsGlobalAuthenticationPolicy –AdditionalAuthenticationProvider “MyMFAAdapter”`
    
  2. 다음으로, MFA를 트리거하도록 전역 또는 신뢰 당사자별 규칙을 구성합니다.

    예제 1: 외부 요청에 MFA를 요구하는 전역 규칙을 만들려면 다음을 수행합니다.

    Set-AdfsAdditionalAuthenticationRule –AdditionalAuthenticationRules 'c:[type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", value == "false"] => issue(type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", value = "http://schemas.microsoft.com/claims/multipleauthn" );'
    

    예제 2: 특정 신뢰 당사자에 대한 외부 요청에 대해 MFA를 요구하는 MFA 규칙을 만듭니다. (참고: 개별 공급자는 Windows Server 2012 R2의 AD FS에서 개별 신뢰 당사자에 연결할 수 없습니다.)

    $rp = Get-AdfsRelyingPartyTrust –Name <Relying Party Name>
    Set-AdfsRelyingPartyTrust –TargetRelyingParty $rp –AdditionalAuthenticationRules 'c:[type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", value == "false"] => issue(type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", value = "http://schemas.microsoft.com/claims/multipleauthn" );'
    

어댑터를 사용하여 MFA로 인증

마지막으로 아래 단계를 수행하여 어댑터를 테스트합니다.

  1. AD FS 전역 기본 인증 유형이 엑스트라넷 및 인트라넷 모두에 대한 양식 인증으로 구성되었는지 확인합니다(데모를 통해 특정 사용자로 더 쉽게 인증할 수 있도록 함).

    1. AD FS 스냅인의 인증 정책 아래 기본 인증 영역에서 전역 설정 옆의 편집클릭합니다.

      1. 또는 다단계 정책 UI에서 기본 탭을 클릭하기만 하면 됩니다.
  2. 엑스트라넷 및 인트라넷 인증 방법 모두에 대해 양식 인증이 검사 유일한 옵션인지 확인합니다. 확인을 클릭합니다.

  3. IDP 시작 로그온 html 페이지(https://< fsname>/adfs/ls/idpinitiatedsignon.htm)를 열고 테스트 환경에서 유효한 AD 사용자로 로그인합니다.

  4. 기본 인증에 대한 자격 증명을 입력합니다.

  5. 예제 챌린지 질문이 표시된 MFA 양식 페이지가 표시됩니다.

    둘 이상의 어댑터를 구성한 경우 위에서 친숙한 이름을 가진 MFA 선택 페이지가 표시됩니다.

    Screenshot of the the M F A forms page with example challenge questions.

    Screenshot of the the M F A choice page.

이제 인터페이스의 작동 구현이 있으며 모델의 작동 방식에 대한 지식이 있습니다. BeginAuthentication 및 TryEndAuthentication에서 중단점을 설정하는 추가 예제로 사용해 볼 수 있습니다. 사용자가 MFA 폼을 처음 입력할 때 BeginAuthentication이 실행되는 방식을 확인합니다. 반면 TryEndAuthentication은 양식의 각 제출에서 트리거됩니다.

성공적인 인증을 위해 어댑터 업데이트

그러나 기다려 - 예제 어댑터는 성공적으로 인증되지 않습니다! 이는 코드의 아무 것도 TryEndAuthentication에 대해 null을 반환하지 않으므로

위의 절차를 완료하여 기본 어댑터 구현을 만들고 AD FS 서버에 추가했습니다. MFA 양식 페이지를 가져올 수 있지만 TryEndAuthentication 구현에 올바른 논리를 아직 배치하지 않았기 때문에 아직 인증할 수 없습니다. 그래서 그것을 추가 할 수 있습니다.

TryEndAuthentication 구현을 기억하세요.

public IAdapterPresentation TryEndAuthentication(IAuthenticationContext authContext, IProofData proofData, HttpListenerRequest request, out Claim[] outgoingClaims)
{
    //return new instance of IAdapterPresentationForm derived class
    outgoingClaims = new Claim[0];
    return new MyPresentationForm();
}

항상 MyPresentationForm()을 반환하지 않도록 업데이트해 보겠습니다. 이를 위해 클래스 내에서 하나의 간단한 유틸리티 메서드를 만들 수 있습니다.

static bool ValidateProofData(IProofData proofData, IAuthenticationContext authContext)
{
    if (proofData == null || proofData.Properties == null || !proofData.Properties.ContainsKey("ChallengeQuestionAnswer"))
    {
        throw new ExternalAuthenticationException("Error - no answer found", authContext);
    }

    if ((string)proofData.Properties["ChallengeQuestionAnswer"] == "adfabric")
    {
        return true;
    }
    else
    {
        return false;
    }
}

그런 다음 아래와 같이 TryEndAuthentication을 업데이트합니다.

public IAdapterPresentation TryEndAuthentication(IAuthenticationContext authContext, IProofData proofData, HttpListenerRequest request, out Claim[] outgoingClaims)
{
    outgoingClaims = new Claim[0];
    if (ValidateProofData(proofData, authContext))
    {
        //authn complete - return authn method
        outgoingClaims = new[]
        {
            // Return the required authentication method claim, indicating the particulate authentication method used.
            new Claim( "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", "http://example.com/myauthenticationmethod1" )
        };
        return null;
    }
    else
    {
        //authentication not complete - return new instance of IAdapterPresentationForm derived class
        return new MyPresentationForm();
    }
}

이제 테스트 상자에서 어댑터를 업데이트해야 합니다. 먼저 AD FS 정책을 실행 취소한 다음 AD FS에서 등록을 취소하고 AD FS를 다시 시작한 다음 GAC에서 .dll을 제거한 다음 새 .dll을 GAC에 추가한 다음 AD FS에 등록하고 AD FS를 다시 시작하고 AD FS 정책을 다시 구성해야 합니다.

테스트 AD FS 컴퓨터에서 업데이트된 어댑터 배포 및 구성

AD FS 정책 지우기

아래에 표시된 MFA UI의 모든 MFA 관련 검사 상자의 지워진 다음 확인을 클릭합니다.

clear policy

공급자 등록 취소(Windows PowerShell)

PS C:> Unregister-AdfsAuthenticationProvider –Name “YourAuthProviderName”

예:PS C:> Unregister-AdfsAuthenticationProvider –Name “MyMFAAdapter”

"Name"에 전달하는 값은 Register-AdfsAuthenticationProvider cmdlet에 제공한 "Name"과 동일한 값입니다. Get-AdfsAuthenticationProvider에서 출력되는 "Name" 속성이기도 합니다.

공급자 등록을 취소하기 전에 AdfsGlobalAuthenticationPolicy에서 공급자를 제거해야 합니다(AD FS 관리 스냅인에서 검사 받은 검사 상자를 선택 취소하거나 Windows PowerShell을 사용하여).

이 작업 후에 AD FS 서비스를 다시 시작해야 합니다.

GAC에서 어셈블리 제거

  1. 먼저 다음 명령을 사용하여 항목의 정규화된 강력한 이름을 찾습니다.C:>.gacutil.exe /l <yourAdapterAssemblyName>

    예:C:>.gacutil.exe /l mfaadapter

  2. 그런 다음, 다음 명령을 사용하여 GAC에서 제거합니다..gacutil /u “<output from the above command>”

    예:C:>.gacutil /u “mfaadapter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e675eb33c62805a0, processorArchitecture=MSIL”

업데이트된 어셈블리를 GAC에 추가

업데이트된 .dll을 먼저 로컬로 붙여넣습니다. C:>.gacutil.exe /if .MFAAdapter.dll

GAC에서 어셈블리 보기(cmd 줄)

C:> .gacutil.exe /l mfaadapter

AD FS에 공급자 등록

  1. PS C:>$typeName = "MFAadapter.MyAdapter, MFAadapter, Version=1.0.0.1, Culture=neutral, PublicKeyToken=e675eb33c62805a0, processorArchitecture=MSIL”

  2. PS C:>Register-AdfsAuthenticationProvider -TypeName $typeName -Name “MyMFAAdapter1”

  3. AD FS 서비스를 다시 시작합니다.

AD FS 관리 스냅인을 사용하여 인증 정책 만들기

  1. 서버 관리자 도구 메뉴에서 AD FS 관리 스냅인을 엽니다.

  2. 인증 정책을 클릭합니다.

  3. Multi-Factor Authentication에서 전역 설정 오른쪽에 있는 편집 링크를 클릭합니다.

  4. 추가 인증 방법 선택에서 공급자의 관리 이름 상자를 검사. 적용을 클릭합니다.

  5. 예를 들어 어댑터를 사용하여 MFA를 호출하는 "트리거"를 제공하려면 위치 검사 엑스트라넷인트라넷을 모두 제공합니다. 확인을 클릭합니다.

어댑터를 사용하여 MFA로 인증

마지막으로 아래 단계를 수행하여 어댑터를 테스트합니다.

  1. AD FS 전역 기본 인증 유형이 엑스트라넷 및 인트라넷 모두에 대한 Forms 인증으로 구성되었는지 확인합니다(이를 통해 특정 사용자로 더 쉽게 인증할 수 있습니다).

    1. AD FS 관리 스냅인의 인증 정책 아래 기본 인증 영역에서 전역 설정 옆의 편집클릭합니다.

      1. 또는 다단계 정책 UI에서 기본 탭을 클릭하기만 하면 됩니다.
  2. 엑스트라넷 및 인트라넷 인증 방법 모두에 대해 양식 인증이 검사 유일한 옵션인지 확인합니다. 확인을 클릭합니다.

  3. IDP 시작 로그온 html 페이지(https://< fsname>/adfs/ls/idpinitiatedsignon.htm)를 열고 테스트 환경에서 유효한 AD 사용자로 로그인합니다.

  4. 기본 인증에 대한 자격 증명을 입력합니다.

  5. 예제 챌린지 텍스트가 표시된 MFA 양식 페이지가 표시됩니다.

    1. 둘 이상의 어댑터를 구성한 경우 이름에 MFA 선택 페이지가 표시됩니다.

MFA 인증 페이지에서 adfabric을 입력할 때 성공적인 로그인이 표시됩니다.

Screenshot of the M F A forms page with example challenge text.

Screenshot of the M F A successful sign in page.

참고 항목

기타 리소스

추가 인증 방법

중요 애플리케이션에 추가 Multi-Factor Authentication을 사용하여 위험 관리