AD FS 2019 위험 평가 모델을 사용하여 플러그 인 빌드
이제부터는 사용자 고유의 플러그 인을 빌드하여 위험을 차단하거나 요청 수신, 사전 인증 및 사후 인증 등 다양한 단계에서 인증 요청에 위험 점수를 할당할 수 있습니다. 이것은 AD FS 2019에 도입된 새로운 위험 평가 모델을 사용하여 실현할 수 있습니다.
위험 평가 모델이란 무엇인가?
위험 평가 모델은 개발자가 인증 요청 헤더를 읽고 자체 위험 평가 논리를 구현할 수 있게 해주는 인터페이스와 클래스 집합입니다. 이후 구현된 코드(플러그 인)는 AD FS 인증 프로세스에 따라 실행됩니다. 예를 들어, 모델에 포함된 인터페이스와 클래스를 사용하여 요청 헤더에 포함된 클라이언트 IP 주소를 기반으로 인증 요청을 차단하거나 허용하는 코드를 구현할 수 있습니다. AD FS는 각 인증 요청에 대해 코드를 실행하고 구현된 논리에 따라 적절하게 조치합니다.
이 모델은 아래와 같이 AD FS 인증 파이프라인 세 단계 중 하나로 코드를 플러그 인할 수 있습니다.
요청 수신 단계 – AD FS가 인증 요청을 수신할 때, 즉 사용자가 자격 증명을 입력하기 전에 플러그 인을 빌드하여 요청을 허용하거나 차단할 수 있습니다. 이 단계에서 사용 가능한 요청 컨텍스트(예: 클라이언트 IP, Http 메서드, 프록시 서버 DNS 등)를 사용하여 위험 평가를 수행할 수 있습니다. 예를 들어, 플러그 인을 빌드하여 요청 컨텍스트에서 IP를 읽고 IP가 미리 정의된 위험한 IP 목록에 있는 경우 인증 요청을 차단할 수 있습니다.
사전 인증 단계 – 사용자가 자격 증명을 제공하지만 AD FS가 평가하기 전인 경우에 플러그 인을 빌드하여 요청을 허용하거나 차단할 수 있습니다. 이 단계에서는 요청 컨텍스트 외에 보안 컨텍스트(예: 사용자 토큰, 사용자 식별자 등)와 위험 평가 논리에 사용할 프로토콜 컨텍스트(예: 인증 프로토콜, clientID, resourceID 등)에 대한 정보도 있습니다. 예를 들어, 사용자 토큰에서 사용자 암호를 읽고 암호가 미리 정의된 위험한 암호 목록에 있는 경우 인증 요청을 차단하는 방식으로 플러그 인을 빌드하여 암호 스프레이 공격을 방지할 수 있습니다.
사후 인증 – 사용자가 자격 증명을 제공하고 AD FS가 인증을 수행한 후에 플러그 인을 빌드하여 위험을 평가할 수 있습니다. 이 단계에서는 요청 컨텍스트, 보안 컨텍스트, 프로토콜 컨텍스트 외에 인증 결과(성공 또는 실패)에 대한 정보도 있습니다. 플러그 인은 사용 가능한 정보를 기반으로 위험 점수를 평가하고, 추가 평가를 위해 위험 점수를 클레임 및 정책 규칙에 전달할 수 있습니다.
위험 평가 플러그 인을 빌드하고 AD FS 프로세스에 따라 실행하는 방법을 더 잘 이해할 수 있도록 위험하다고 확인된 특정 엑스트라넷 IP에서 들어오는 요청을 차단하는 샘플 플러그 인을 빌드하여, AD FS에 플러그 인을 등록하고, 마지막으로 기능을 테스트해 보겠습니다.
참고 항목
또는 Microsoft Entra ID Protection에서 확인한 사용자 위험 수준을 활용하여 인증을 차단하거나 MFA(다단계 인증)를 적용하는 샘플 플러그 인인 위험한 사용자 플러그 인을 빌드할 수 있습니다. 위험한 사용자 플러그 인을 빌드하는 단계는 여기에서 사용할 수 있습니다.
샘플 플러그 인 빌드
참고 항목
이 연습에서는 샘플 플러그 인을 만드는 방법만 보여줍니다. 우리가 만들 솔루션은 엔터프라이즈 지원 솔루션이 아닙니다.
필수 구성 요소
이 샘플 플러그 인을 빌드하는 데 필요한 필수 구성 요소 목록은 다음과 같습니다.
- AD FS 2019 설치 및 구성 완료 상태
- .NET Framework 4.7 이상
- Visual Studio
플러그 인 dll 빌드
다음 절차에서는 샘플 플러그 인 dll을 빌드하는 단계를 설명합니다.
샘플 플러그인을 다운로드한 후, Git Bash를 사용하고, 다음을 입력합니다.
git clone https://github.com/Microsoft/adfs-sample-RiskAssessmentModel-RiskyIPBlock
AD FS 서버의 모든 위치에 .csv 파일을 만들고(제 경우에는 C:\extensions에서 authconfigdb.csv 파일을 만들었음) 이 파일에 차단하려는 IP를 추가합니다.
샘플 플러그 인은 이 파일에 나열된 엑스트라넷 IP에서 들어오는 모든 인증 요청을 차단합니다.
참고 항목
AD FS 팜이 있으면 모든 AD FS 서버에서 파일을 만들 수 있습니다. 어느 파일이든 사용하여 위험한 IP를 AD FS로 가져올 수 있습니다. 아래 AD FS로 플러그 인 dll 등록 섹션에서 가져오기 프로세스를 자세히 설명합니다.
Visual Studio를 사용하여 프로젝트
ThreatDetectionModule.sln
를 엽니다.아래와 같이 솔루션 탐색기에서
Microsoft.IdentityServer.dll
를 제거합니다.아래와 같이 AD FS의
Microsoft.IdentityServer.dll
에 참조를 추가합니다.a. 솔루션 탐색기에서 참조를 마우스 오른쪽 단추로 클릭하고 참조 추가를 선택합니다.
b. 참조 관리자 창에서 찾아보기를 선택합니다. 참조할 파일 선택... 대화 상자에서 AD FS 설치 폴더(제 경우는 C:\Windows\ADFS)에서
Microsoft.IdentityServer.dll
를 선택하고 추가를 클릭합니다.참고 항목
저는 AD FS 서버 자체에서 플러그 인을 빌드합니다. 개발 환경이 다른 서버에 있는 경우에는
Microsoft.IdentityServer.dll
를 AD FS 서버의 AD FS 설치 폴더에서 개발 상자로 복사합니다.c.
Microsoft.IdentityServer.dll
확인란이 선택되어 있는지 확인한 후에 참조 관리자에서 확인을 클릭합니다.이제 모든 클래스와 참조가 빌드를 수행할 준비가 되었습니다. 단, 이 프로젝트의 출력은 dll이므로 AD FS 서버의 전역 어셈블리 캐시 또는 GAC에 설치해야 하며 dll을 먼저 서명해야 합니다. 이는 다음을 따라 수행할 수 있습니다.
a. 프로젝트의 이름인 ThreatDetectionModule을 마우스 오른쪽 단추로 클릭합니다 . 메뉴에서 속성을 클릭합니다.
b. 속성 페이지에서 서명을 클릭하고 왼쪽에서 어셈블리 서명으로 표시된 확인란을 선택합니다. 강력한 이름 키 파일 선택 풀다운 목메뉴에서 <새로 만들기>를 선택합니다.
c. 강력한 이름 키 만들기 대화 상자에서 키의 이름(원하는 이름을 선택할 수 있음)을 입력하고 암호로 내 키 파일 보호 확인란의 선택을 취소합니다. 그런 다음 확인을 클릭합니다.
d. 아래와 같이 프로젝트를 저장합니다.
빌드를 클릭한 다음 아래와 같이 솔루션 다시 빌드를 클릭하여 프로젝트를 빌드합니다.
화면 아래쪽의 출력 창을 확인하여 오류가 발생했는지 확인합니다.
이제 플러그 인(dll)이 사용할 준비가 되었으며 프로젝트 폴더의 \bin\Debug 폴더에 있습니다(제 경우에는 C:\extensions\ThreatDetectionModule\bin\Debug\ThreatDetectionModule.dll입니다).
다음 단계는 AD FS 인증 프로세스에 따라 실행되도록 이 dll을 AD FS에 등록하는 것입니다.
AD FS에 플러그 인 dll 등록
AD FS 서버의 Register-AdfsThreatDetectionModule
PowerShell 명령을 사용하여 AD FS에 dll을 등록해야 합니다. 단, 등록 전에 공개 키 토큰을 가져와야 합니다. 이 공개 키 토큰은 키를 만들고 해당 키를 사용하여 dll에 서명할 때 만들어진 것입니다. dll에 대한 공개 키 토큰이 무엇인지 알아보려면 다음과 같이 SN.exe를 사용하면 됩니다.
\bin\Debug 폴더의 dll 파일을 다른 위치로 복사합니다(제 경우에는 C:\extensions로 복사).
Visual Studio용 개발자 명령 프롬프트를 시작하고 sn.exe를 포함하는 디렉터리로 이동합니다(내 경우에는 디렉터리가 C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 도구임).
-T 매개 변수 및 파일의 위치(제 경우는
SN -T "C:\extensions\ThreatDetectionModule.dll"
)를 사용하여 SN 명령을 실행합니다.이 명령은 공개 키 토큰을 제공합니다(제 경우는 공개 키 토큰이 714697626ef96b35입니다).
AD FS 서버의 전역 어셈블리 캐시에 dll을 추가합니다. 가장 좋은 방법은 프로젝트에 적합한 설치 관리자를 만들고 설치 관리자를 사용하여 GAC에 파일을 추가하는 것입니다. 또 다른 해결 방법은 개발 머신에서 Gacutil.exe(여기에서 사용할 수 있는 Gacutil.exe 대한 자세한 정보)를 사용하는 것입니다. 저는 AD FS와 동일한 서버에 Visual Studio가 있어 다음과 같이 Gacutil.exe를 사용하겠습니다.
a. Visual Studio용 개발자 명령 프롬프트에서 Gacutil.exe가 있는 디렉터리로 이동합니다(제 경우는 디렉터리가 C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 도구입니다).
b. Gacutil 명령을 실행합니다(제 경우에는
Gacutil /IF C:\extensions\ThreatDetectionModule.dll
).참고 항목
AD FS 팜이 있다면 팜의 각 AD FS 서버에서 위의 작업을 실행해야 합니다.
Windows PowerShell을 열고 다음 명령을 실행하여 dll을 등록합니다.
Register-AdfsThreatDetectionModule -Name "<Add a name>" -TypeName "<class name that implements interface>, <dll name>, Version=10.0.0.0, Culture=neutral, PublicKeyToken=< Add the Public Key Token from Step 2. above>" -ConfigurationFilePath "<path of the .csv file>"
제 경우의 명령은 다음과 같습니다.
Register-AdfsThreatDetectionModule -Name "IPBlockPlugin" -TypeName "ThreatDetectionModule.UserRiskAnalyzer, ThreatDetectionModule, Version=10.0.0.0, Culture=neutral, PublicKeyToken=714697626ef96b35" -ConfigurationFilePath "C:\extensions\authconfigdb.csv"
참고 항목
AD FS 팜이 있어도 dll을 한 번만 등록해야 합니다.
dll 등록 후에 AD FS 서비스를 다시 시작합니다.
이제 dll이 AD FS에 등록되어 사용할 수 있습니다.
참고 항목
플러그 인을 변경하여 프로젝트가 다시 빌드된 경우 업데이트된 dll을 다시 등록해야 합니다. 등록 전에 다음 명령을 사용하여 현재 dll의 등록을 취소해야 합니다.
UnRegister-AdfsThreatDetectionModule -Name "<name used while registering the dll in 5. above>"
제 경우의 명령은 다음과 같습니다.
UnRegister-AdfsThreatDetectionModule -Name "IPBlockPlugin"
플러그 인 테스트
앞에서 만든 authconfig.csv 파일을 열고(제 경우는 C:\extensions 위치) 차단할 엑스트라넷 IP를 추가합니다. 모든 IP가 별도의 줄에 있어야 하며 끝에 공백이 없어야 합니다.
파일을 저장 후 닫습니다.
다음 PowerShell 명령을 실행하여 AD FS에서 업데이트된 파일을 가져옵니다.
Import-AdfsThreatDetectionModuleConfiguration -name "<name given while registering the dll>" -ConfigurationFilePath "<path of the .csv file>"
제 경우의 명령은 다음과 같습니다.
Import-AdfsThreatDetectionModuleConfiguration -name "IPBlockPlugin" -ConfigurationFilePath "C:\extensions\authconfigdb.csv")
authconfig.csv에서 추가한 것과 동일한 IP를 사용하여 서버에서 인증 요청을 시작합니다.
이 데모에서는 AD FS 도움말 클레임 X-Ray 도구를 사용하여 요청을 시작합니다. X-Ray 도구를 사용하고 싶으시면 지침을 따르세요.
페더레이션 서버 인스턴스를 입력하고 테스트 인증 단추를 누릅니다.
아래와 같이 인증이 차단됩니다.
이제 플러그 인을 빌드하고 등록하는 방법을 알았으니 플러그 인 코드를 연습하여 이 모델에 도입된 새 인터페이스와 클래스를 사용하여 구현을 이해해보겠습니다.
플러그 인 코드 연습
Visual Studio를 사용하여 프로젝트 ThreatDetectionModule.sln
를 연 다음 화면 오른쪽의 솔루션 탐색기에서 주 파일 UserRiskAnalyzer.cs 엽니다.
이 파일에는 추상 클래스 ThreatDetectionModule와 인터페이스 IRequestReceivedThreatDetectionModule를 구현하여 요청 컨텍스트에서 IP를 읽고, 가져온 IP를 FS DB에서 로드한 IP와 비교하고, IP 일치가 있으면 요청을 차단하는 주 클래스 UserRiskAnalyzer가 포함되어 있습니다. 이러한 형식을 자세히 살펴보겠습니다.
ThreatDetectionModule 추상 클래스
이 추상 클래스는 AD FS 파이프라인으로 플러그 인을 로드하므로 AD FS 프로세스에 따라 플러그 인 코드를 실행할 수 있습니다.
public abstract class ThreatDetectionModule
{
protected ThreatDetectionModule();
public abstract string VendorName { get; }
public abstract string ModuleIdentifier { get; }
public abstract void OnAuthenticationPipelineLoad(ThreatDetectionLogger logger, ThreatDetectionModuleConfiguration configData);
public abstract void OnAuthenticationPipelineUnload(ThreatDetectionLogger logger);
public abstract void OnConfigurationUpdate(ThreatDetectionLogger logger, ThreatDetectionModuleConfiguration configData);
}
이 클래스에는 다음 메서드와 속성이 포함됩니다.
메서드 | Type | 정의 |
---|---|---|
OnAuthenticationPipelineLoad | Void | 플러그 인이 파이프라인으로 로드될 때 AD FS에서 호출됨 |
OnAuthenticationPipelineUnload | Void | 플러그 인이 파이프라인에서 언로드될 때 AD FS에서 호출됨 |
OnConfigurationUpdate | Void | 구성 업데이트에서 AD FS에 의해 호출됨 |
속성 | Type | 정의 |
VendorName | 문자열 | 플러그 인을 소유한 공급업체의 이름을 가져옵니다. |
ModuleIdentifier | 문자열 | 플러그인의 식별자를 가져옵니다. |
샘플 플러그 인에서는 OnAuthenticationPipelineLoad 및 OnConfigurationUpdate 메서드를 사용하여 AD FS DB에서 미리 정의된 IP를 읽습니다. onAuthenticationPipelineLoad는 플러그 인이 AD FS에 등록될 때 호출되고, Import-AdfsThreatDetectionModuleConfiguration
cmdlet을 사용하여 .csv를 가져올 때 OnConfigurationUpdate가 호출됩니다.
IRequestReceivedThreatDetectionModule 인터페이스
이 인터페이스를 사용하면 AD FS가 인증 요청을 수신하는 시점에 위험 평가를 구현할 수 있지만 사용자가 자격 증명을 입력하기 전에(예: 인증 프로세스의 수신된 요청 단계에서) 위험 평가를 구현할 수 있습니다.
public interface IRequestReceivedThreatDetectionModule
{
Task<ThrottleStatus> EvaluateRequest (
ThreatDetectionLogger logger,
RequestContext requestContext );
}
이 인터페이스에는 requestContext 입력 매개 변수에 전달된 인증 요청의 컨텍스트를 사용하여 위험 평가 논리를 작성할 수 있는 EvaluateRequest 메서드가 포함되어 있습니다. requestContext 매개 변수는 RequestContext 형식입니다.
전달된 다른 입력 매개 변수는 ThreatDetectionLogger 형식의 로거입니다. 이 매개 변수를 사용하여 AD FS 로그에 오류, 감사 및/또는 디버그 메시지를 작성할 수 있습니다.
이 메서드는 요청을 차단하거나 허용하는 AD FS에 ThrottleStatus(NotEvaluated인 경우 0, 블록에 1, 허용하려면 2)를 반환합니다.
샘플 플러그 인에서 EvaluateRequest 메서드 구현은 requestContext 매개 변수에서 clientIpAddress를 구문 분석하고 AD FS DB에서 로드된 모든 IP와 비교합니다. 일치 항목이 발견되면 메서드는 Block에 대해 2를 반환하고, 그렇지 않으면 Allow에 대해 1을 반환합니다. 반환된 값에 따라 AD FS가 요청을 차단하거나 허용합니다.
참고 항목
위에서 다룬 샘플 플러그 인은 IRequestReceivedThreatDetectionModule 인터페이스만 구현합니다. 단, 위험 평가 모델은 두 개의 추가 인터페이스인 IPreAuthenticationThreatDetectionModule(위험 평가 논리 duing 사전 인증 단계를 구현하기 위해) 및 IPostAuthenticationThreatDetectionModule(인증 후 단계 동안 위험 평가 논리를 구현하기 위해)을 제공합니다. 두 인터페이스에 관한 세부 정보는 다음과 같습니다.
IPreAuthenticationThreatDetectionModule 인터페이스
이 인터페이스를 사용하면 사용자가 자격 증명을 제공하는 시점에 위험 평가 논리를 구현할 수 있지만 AD FS가 평가하기 전(예: 사전 인증 단계)을 구현할 수 있습니다.
public interface IPreAuthenticationThreatDetectionModule
{
Task<ThrottleStatus> EvaluatePreAuthentication (
ThreatDetectionLogger logger,
RequestContext requestContext,
SecurityContext securityContext,
ProtocolContext protocolContext,
IList<Claim> additionalClams
);
}
이 인터페이스에는 RequestContext requestContext, SecurityContext securityContext, ProtocolContext protocolContext, IList<Claim> additionalClams 입력 매개 변수에서 전달되는 정보를 사용하여 사전 인증 위험 평가 논리를 작성하는 EvaluatePreAuthentication 메서드가 포함되어 있습니다.
참고 항목
각 컨텍스트 형식으로 전달된 속성 목록을 보려면 RequestContext, SecurityContext, ProtocolContext 클래스 정의를 방문하세요.
전달된 다른 입력 매개 변수는 ThreatDetectionLogger 형식의 로거입니다. 이 매개 변수를 사용하여 AD FS 로그에 오류, 감사 및/또는 디버그 메시지를 작성할 수 있습니다.
이 메서드는 요청을 차단하거나 허용하는 AD FS에 ThrottleStatus(NotEvaluated인 경우 0, 블록에 1, 허용하려면 2)를 반환합니다.
IPostAuthenticationThreatDetectionModule 인터페이스
이 인터페이스를 사용하면 사용자가 자격 증명을 제공하고 AD FS가 인증을 수행한 후(예: 인증 후 단계) 위험 평가 논리를 구현할 수 있습니다.
public interface IPostAuthenticationThreatDetectionModule
{
Task<RiskScore> EvaluatePostAuthentication (
ThreatDetectionLogger logger,
RequestContext requestContext,
SecurityContext securityContext,
ProtocolContext protocolContext,
AuthenticationResult authenticationResult,
IList<Claim> additionalClams
);
}
이 인터페이스에는 RequestContext requestContext, SecurityContext securityContext, ProtocolContext protocolContext, IList<Claim> additionalClams 입력 매개 변수에서 전달되는 정보를 사용하여 사후 인증 위험 평가 논리를 작성하는 EvaluatePostAuthentication 메서드가 포함되어 있습니다.
참고 항목
각 컨텍스트 형식으로 전달된 전체 속성 목록은 RequestContext, SecurityContext, ProtocolContext 클래스 정의를 참조하세요.
전달된 다른 입력 매개 변수는 ThreatDetectionLogger 형식의 로거입니다. 이 매개 변수를 사용하여 AD FS 로그에 오류, 감사 및/또는 디버그 메시지를 작성할 수 있습니다.
이 메서드는 AD FS 정책 및 클레임 규칙에 사용할 수 있는 위험 점수를 반환합니다.
참고 항목
플러그 인이 작동하려면 주 클래스(이 경우 UserRiskAnalyzer)는 ThreatDetectionModule 추상 클래스를 파생해야 하며 위에서 설명한 세 가지 인터페이스 중 하나 이상을 구현해야 합니다. dll이 등록되면 AD FS가 구현되는 인터페이스를 확인하고 파이프라인의 적절한 단계에서 호출합니다.
FAQ
왜 이러한 플러그 인을 빌드해야 하나요?
A: 이러한 플러그 인은 암호 스프레이 공격과 같은 공격으로부터 환경을 보호하는 추가 기능을 제공할 뿐만 아니라 요구 사항에 따라 고유한 위험 평가 논리를 유연하게 빌드할 수 있습니다.
로그는 어디에 캡처되나요?
A: WriteAdminLogErrorMessage 메서드를 사용하여 "AD FS/Admin" 이벤트 로그에 오류 로그를 작성하고, WriteAuditMessage 메서드를 사용하여 "AD FS 감사" 보안 로그에 로그를 감사하고, WriteDebugMessage 메서드를 사용하여 로그를 "AD FS 추적" 디버그 로그에 디버그할 수 있습니다.
이러한 플러그 인을 추가하면 AD FS 인증 프로세스 대기 시간이 증가하나요?
A: 대기 시간 영향은 구현하는 위험 평가 논리를 실행하는 데 걸린 시간에 따라 결정됩니다. 대기 시간 영향을 평가한 후에 프로덕션 환경에서 플러그 인을 배포하는 것이 좋습니다.
AD FS에서 위험한 IP, 사용자 등의 목록을 제안할 수 없는 이유는 무엇인가요?
A: 지금은 사용할 수 없지만 플러그형 위험 평가 모델에서 위험한 IP, 사용자 등을 제안하는 인텔리전스를 빌드하기 위해 노력하고 있습니다. 출시 날짜를 곧 알려드릴 것입니다.
사용할 수 있는 다른 샘플 플러그 인은 무엇인가요?
A: 다음과 같은 샘플 플러그 인을 사용할 수 있습니다.
속성 | 설명 |
---|---|
위험한 사용자 플러그 인 | Microsoft Entra ID Protection으로 확인된 사용자 위험 수준에 따라 인증을 차단하거나 MFA를 적용하는 샘플 플러그 인입니다. |