다음을 통해 공유


ACS 보안 지침

업데이트: 2015년 6월 19일

적용 대상: Azure

적용 대상

  • Microsoft Azure Active Directory Access Control(Access Control Service 또는 ACS라고도 함)

  • WIF(Windows Identity Foundation)

요약

이 항목에서는 ACS에 대한 보안 지침을 통합합니다. 다음 지침을 사용하여 보안 관점에서 구현의 품질을 개선합니다. 애플리케이션의 아키텍처를 검토하고, 코드를 검토하고, 보안 버그를 로깅하고, 프로덕션 배포를 검토할 때 이러한 지침을 사용할 수 있습니다. 이러한 지침은 특정 작업을 수행하기 위한 규범적 단계를 포함하는 방법 및 ACS의 특정 기능 또는 기능에 대해 자세히 알아보기 위한 개념 항목에 대한 자세한 내용을 참조합니다.

목표

  • ACS 컨텍스트에서 애플리케이션의 코드 및 구성과 관련된 보안 문제를 해결합니다.

  • ACS 구성과 관련된 보안 문제를 해결합니다.

  • ACS 컨텍스트에서 Azure 배포와 관련된 보안 문제를 해결합니다.

다음은 애플리케이션의 코드 및 구성과 관련된 보안 지침입니다.

  • 재생 검색 기능(DetectReplayedTokens)을 true로 설정하는 것이 좋습니다.

  • wsFederation requireHttps 특성을 true로 설정합니다.

  • cookieHandler requireSsl 특성을 true로 설정합니다.

  • sessionTokenRequirement수명 특성에 대한 공격적인 값을 설정합니다.

  • issuerNameRegistry신뢰할 수 있는 STS(토큰 발급자)를 나열합니다.

  • audienceUri사용하여 애플리케이션에서 수락해야 하는 범위 토큰입니다.

재생 검색 기능(DetectReplayedTokens)을 true로 설정하는 것이 좋습니다.

WIF에는 이전에 사용한 STS 토큰의 캐시인 STS(보안 토큰 서비스) 전달자 토큰을 위한 재생 검색 캐시가 있습니다. 클라이언트가 STS 토큰을 사용하여 신뢰 당사자에 처음 인증하는 경우 추가 요청에 대해 신뢰 당사자에 인증하는 데 사용하는 세션 보안 토큰을 받습니다. 세션 보안 토큰을 도난할 수 없도록 SSL(Secure Sockets Layer)을 통해 이 작업을 수행합니다. 클라이언트 또는 공격자가 클라이언트가 이미 사용한 STS 토큰으로 신뢰 당사자에 인증을 시도하는 경우 신뢰 당사자는 재생 캐시에서 STS 토큰을 조회하고 요청을 거부할 수 있습니다.

이 캐시는 토큰을 재생할 수 없음을 보장하지 않습니다. 캐시 크기, STS 토큰의 만료 시간 및 신뢰 당사자가 수신한 고유 인증 요청 속도에 따라 최상의 검색을 수행합니다. 신뢰 당사자가 성능과 보안 간에 적절한 균형을 맞추기 위해 캐시 크기 및 STS 토큰 만료 시간을 설정하는 것이 좋습니다.

본보기:

<securityTokenHandlers>
  <securityTokenHandlerConfiguration>
    <tokenReplayDetection enabled="true" capacity="1000" expirationPeriod="500"/>
  </securityTokenHandlerConfiguration>
</securityTokenHandlers>

메모

이 기능을 사용하면 Azure를 비롯한 부하 분산 환경에서 확장성 문제가 발생할 수 있는 서버 선호도가 도입됩니다. 이를 극복하기 위해 Microsoft.IdentityModel.Tokens.Tokens.Tokens.TokenReplayC ache 기본 추상 클래스를 사용하여 사용자 고유의 토큰 재생 검색을 구현한 다음, 다음과 유사한 코드를 사용하여 구성 파일에서 참조하는 것이 좋습니다.

<system.identityModel>
  <identityConfiguration>
    <tokenReplayDetection>
      <replayCache type='FQTN of your type' />
    </tokenReplayDetection>
  </identityConfiguration>
</system.identityModel>

wsFederation의 requireHttps 특성을 true로 설정합니다.

requireHttps 특성은 모듈이 STS에 대한 보안 URL만 리디렉션할지 여부를 제어합니다. 기본값은 "true"입니다. 이렇게 하면 명확한 HTTPS/SSL 트래픽을 통해 STS와의 보안 통신을 보장하여 통신을 통해 자격 증명 및 토큰 검색을 완화합니다.

본보기:

<federatedAuthentication>
  <wsFederation
        passiveRedirectEnabled="true"
        issuer="http://STS URL GOES HERE/"
        realm="http://RP REALM GOES HERE/"
        requireHttps="ture" />
  <cookieHandler requireSsl="true" />
</federatedAuthentication>

cookieHandler의 requireSsl 특성을 true로 설정합니다.

이 값은 부울입니다. 기본값은 false입니다. requireSsl 특성은 기록된 쿠키에 대해 "보안" 플래그가 내보내지는지 여부를 제어합니다. 이 값을 설정하면 로그인 세션 쿠키는 HTTPS를 통해서만 사용할 수 있습니다. 이렇게 하면 명확한 트래픽을 통해 세션 쿠키를 전송하여 통신을 통해 토큰이 스니핑되는 위협을 완화할 수 있습니다.

본보기:

<federatedAuthentication>
  <wsFederation
        passiveRedirectEnabled="true"
        issuer="http://STS URL GOES HERE/"
        realm="http://RP REALM GOES HERE/"
        requireHttps="ture" />
  <cookieHandler requireSsl="true" />
</federatedAuthentication>

sessionTokenRequirement의 수명 특성에 대한 공격적인 값 설정

토큰을 적극적인 수명 제한으로 발급하도록 요구하는 것이 좋습니다. 이렇게 하면 도난당한 경우 토큰을 재생하기 위한 공격자의 시간 프레임이 제한됩니다.

본보기:

<add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel">
  <sessionTokenRequirement securityTokenCacheType="Microsoft.IdentityModel.MruSecurityTokenCache, Microsoft.IdentityModel"
                           saveBootstrapTokens="true"
                           securityTokenCacheSize="500"
                           useWindowsTokenService="false"
                           lifetime="10:00" />
</add>

issuerNameRegistry에서 신뢰할 수 있는 STS(토큰 발급자) 나열

모든 발급자 토큰은 IssuerNameRegistry를 사용하여 유효성을 검사합니다. IssuerNameRegistry의 목적은 발급자 토큰을 문자열 이름에 매핑하는 것입니다. 유효성 검사에 실패하면 토큰이 허용되지 않습니다. 이렇게 하면 신뢰할 수 없는 토큰을 수락하는 위협이 완화됩니다. 모든 사용자 지정 형식은 <issuerNameRegistry> 요소의 형식 특성을 사용하여 등록할 수 있습니다. <issuerNameRegistry> IssuerNameRegistry에 대한 사용자 지정 구성으로 사용할 자식 요소를 하나 가질 수 있습니다. 구성에서 신뢰할 수 있는 발급자 인증서 집합을 구성하는 데 사용할 수 있는 하나의 IssuerNameRegistry 유형인 ConfigurationBasedIssuerNameRegistry가 기본 제공됩니다. 이 형식에는 신뢰할 수 있는 발급자 인증서가 구성된><자식 구성 요소가 필요합니다. <trustedIssuers> 구성은 ASN.1로 인코딩된 형식의 인증서 지문을 사용하여 신뢰할 수 있는 인증서를 추가합니다.

본보기:

<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel">
  <trustedIssuers>
    <add thumbprint="97249e1a5fa6bee5e515b82111ef524a4c9158de" name="contoso.com" />
    <remove thumbprint="97249e1a5fa6bee5e515b82111ef524a4c9158de" />
    <clear/>
  </trustedIssuers>
</issuerNameRegistry>

audienceUri만 사용하여 애플리케이션에 대한 토큰 범위 지정

<audienceUris> 이 신뢰 당사자를 식별하는 것으로 허용되는 URI 집합을 지정합니다. 토큰은 허용된 대상 그룹 URI 중 하나에 대해 범위가 지정되지 않는 한 허용되지 않습니다. 이렇게 하면 다른 신뢰 당사자에 대해 발급된 유효한 토큰을 재생하는 위협이 완화됩니다. 기본적으로 컬렉션에 URI가 추가되지 않습니다. SAML 1.1 및 SAML 2.0 토큰 형식에 대한 SecurityTokenHandler는 이 컬렉션의 값을 사용하여 SamlSecurityTokenRequirement 개체에서 허용되는 모든 대상 그룹 URI 제한을 구성합니다.

본보기:

<audienceUris>
  <clear/>
  <add value="http://www.example.com/myapp/" />
  <remove value="http://www.example.com/myapp/" />
</audienceUris>

다음은 ACS 관리 포털 구성과 관련된 보안 지침입니다.

  • STS 토큰에 대한 적극적인 만료 설정

  • 오류 URL 기능을 사용할 때 적절한 데이터 유효성 검사 제공

  • 매우 중요한 시나리오에 대한 토큰 암호화 고려

STS 토큰에 대한 적극적인 만료 설정

토큰 수명 특성은 토큰의 수명을 제어합니다. ACS 포털 또는 관리 서비스를 사용하여 신뢰 당사자를 만들거나 구성할 때 지정됩니다. 토큰 수명 속성을 사용하여 ACS에서 신뢰 당사자 애플리케이션에 발급한 보안 토큰이 유효한 상태를 유지하는 데 걸리는 시간을 지정할 수 있습니다. 기본적으로 ACS에서 이 값은 10분(600초)으로 설정됩니다. ACS에서 이 값은 0보다 크지만 24시간(86400초)보다 작거나 같아야 합니다.

오류 URL 기능을 사용할 때 적절한 데이터 유효성 검사 제공

오류 URL을 사용하여 로그인 프로세스 중에 오류가 발생할 경우 ACS가 사용자를 리디렉션하는 URL을 지정할 수 있습니다. 신뢰 당사자 애플리케이션에서 호스트되는 사용자 지정 페이지일 수 있습니다(예: http://www.fabrikam.com/billing/error.aspx.). 리디렉션의 일부로 ACS는 JSON 인코딩 HTTP URL 매개 변수로 신뢰 당사자 애플리케이션에 오류에 대한 세부 정보를 제공합니다. JSON으로 인코딩된 오류 정보를 사용하여 받은 실제 오류 메시지를 렌더링하거나 정적 도움말 텍스트를 표시하도록 사용자 지정 오류 페이지를 만들 수 있습니다. 페이지에 권한 부여가 필요한 경우 ACS가 액세스하고 JSON 인코딩 오류를 보내려고 하는 경우 결과는 무한 리디렉션 루프가 됩니다. 따라서 익명 액세스를 위해 구성해야 합니다. 페이지에 익명으로 액세스할 수 있고 HTML을 다시 에코하거나 데이터베이스에 데이터를 쓰는 코드가 포함될 수 있으므로 교차 사이트 스크립팅 및 SQL 삽입 공격을 방지하기 위한 단계를 수행해야 합니다.

매우 중요한 시나리오에 대한 토큰 암호화 고려

수동 페더레이션에 대한 매우 중요한 시나리오의 경우 토큰 암호화를 고려합니다. 인증서 및 키 항목에서 토큰 암호화 및 암호 해독에 대해 자세히 알아보세요.

다음은 ACS를 사용하고 Azure에 배포되는 애플리케이션과 관련된 보안 고려 사항입니다.

  • RSA를 사용하여 쿠키 암호화

RSA를 사용하여 쿠키 암호화

Azure에서는 각 인스턴스에 다른 키가 있기 때문에 기본 쿠키 암호화 메커니즘(DPAPI(데이터 보호 애플리케이션 프로그래밍 인터페이스)을 사용하는 것은 적절하지 않습니다. 즉, 한 웹 역할 인스턴스에서 만든 쿠키는 다른 웹 역할 인스턴스에서 읽을 수 없습니다. 이로 인해 서비스 오류가 발생하여 서비스 거부가 발생할 수 있습니다. 다음은 기본 쿠키 암호화 메커니즘을 사용하는 경우 발생하는 오류 메시지입니다.

[CryptographicException: Key not valid for use in specified state.
]
System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope) +577
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +80
[InvalidOperationException: ID1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false. ]
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +433
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound) +189
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) +862
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) +109
Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie) +356
Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) +123
Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +61
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270

이 문제를 해결하려면 모든 웹 역할 인스턴스에서 공유하는 키를 사용하는 쿠키 암호화 메커니즘을 사용합니다. 다음 코드에서는 기본 SessionSecurityHandler 개체를 바꾸고 RsaEncryptionCookieTransform 클래스를 사용하도록 구성하는 방법을 보여 줍니다.

private void OnServiceConfigurationCreated(object sender, 
    ServiceConfigurationCreatedEventArgs e)
{
    List<CookieTransform> sessionTransforms =
        new List<CookieTransform>(
            new CookieTransform[] 
            {
                new DeflateCookieTransform(), 
                new RsaEncryptionCookieTransform(
                    e.ServiceConfiguration.ServiceCertificate),
                new RsaSignatureCookieTransform(
                    e.ServiceConfiguration.ServiceCertificate)  
            });
   SessionSecurityTokenHandler sessionHandler = 
    new
     SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());

    e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(
        sessionHandler);
}

void Application_Start(object sender, EventArgs e)
{
    FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;
}

추가 리소스