Microsoft ID 플랫폼 및 OAuth 2.0 클라이언트 자격 증명 흐름

애플리케이션의 ID를 사용하여 웹 호스팅 리소스에 액세스하기 위해 RFC 6749에 명시된 OAuth 2.0 클라이언트 자격 증명 권한 부여(때로는 2단계 OAuth 라고도 함)를 사용할 수 있습니다. 이 유형의 권한 부여는 일반적으로 사용자의 직접적인 상호 작용 없이 백그라운드에서 실행해야 하는 서버 간 상호 작용에 사용됩니다. 이러한 유형의 애플리케이션은 종종 디먼 또는 서비스 계정 이라고 합니다.

이 문서에서는 애플리케이션에서 프로토콜에 대해 직접 프로그래밍을 수행하는 방법을 설명합니다. 가능하면 토큰을 획득하고 보안 Web API를 호출하는 대신, 지원되는 MSAL(Microsoft 인증 라이브러리)을 사용하는 것이 좋습니다. MSAL을 사용하는 샘플 앱도 살펴봅니다.

OAuth 2.0 클라이언트 자격 증명 부여 흐름을 사용하면 웹 서비스(비밀 클라이언트)에서 다른 웹 서비스를 호출할 때 사용자를 가장하는 대신 고유한 자격 증명을 사용하여 인증할 수 있습니다. 더 높은 수준의 보증을 위해 Microsoft ID 플랫폼은 호출 서비스가 자격 증명으로 인증서(공유 비밀 대신)를 사용할 수 있도록 합니다. 애플리케이션 자체 자격 증명을 사용하므로 이러한 자격 증명은 안전하게 보관해야 합니다. 소스 코드에서 해당 자격 증명을 게시하거나 웹 페이지에 포함하거나 널리 분산된 네이티브 애플리케이션에서 절대 사용하지 마세요.

클라이언트 자격 증명 흐름에서는 관리자가 애플리케이션 자체에 직접 사용 권한을 부여합니다. 앱이 리소스에 대한 토큰을 제공하는 경우 리소스는 인증에 관련된 사용자가 없으므로 앱 자체에 작업을 수행할 수 있는 권한을 부여합니다. 이 문서에서는 API를 호출하는 애플리케이션에 권한을 부여하는 데 필요한 단계와 API를 호출하는 데 필요한 토큰을 가져오는 방법에 대해 설명합니다.

Postman에서 이 요청을 실행해 보세요
Postman에서 이 요청 등을 사용해 보세요. 토큰 및 ID를 바꾸어야 합니다.

프로토콜 다이어그램

전체 클라이언트 자격 증명 흐름은 다음 다이어그램과 유사합니다. 이 문서의 뒷부분에서 각 단계에 대해 설명합니다.

클라이언트 자격 증명 흐름을 보여 주는 다이어그램

직접 권한 부여 가져오기

앱은 일반적으로 두 가지 방법 중 하나로 리소스에 액세스할 수 있는 직접 권한을 부여받습니다.

이러한 두 메서드는 Azure AD에서 가장 일반적이며 클라이언트 자격 증명 흐름을 수행하는 클라이언트 및 리소스에 사용하는 것이 좋습니다. 또한 리소스가 다른 방식으로 해당 클라이언트를 인증하도록 선택할 수 있습니다. 각 리소스 서버가 해당 애플리케이션에 가장 적합한 방법을 선택할 수 있습니다.

액세스 제어 목록

리소스 공급자는 특정 수준의 액세스를 알고 권한을 부여하는 애플리케이션(클라이언트) ID 목록에 따라 권한 부여 확인을 적용할 수 있습니다. 리소스가 Microsoft ID 플랫폼에서 토큰을 받으면 토큰을 디코딩하고 appidiss 클레임에서 클라이언트의 애플리케이션 ID를 추출할 수 있습니다. 그런 다음, 유지 관리하는 ACL(액세스 제어 목록)에 대해 애플리케이션을 비교합니다. ACL의 세분성 및 메서드는 리소스 간에 크게 달라질 수 있습니다.

일반적인 사용 사례는 ACL을 사용하여 웹 애플리케이션 또는 웹 API에 대한 테스트를 실행하는 것입니다. 웹 API는 특정 클라이언트에 대한 모든 권한의 하위 집합만 부여할 수 있습니다. API에서 엔드투엔드 테스트를 실행하려면 Microsoft ID 플랫폼에서 토큰을 획득하여 API에 전송하는 테스트 클라이언트를 만듭니다. 그러면 API는 API의 전체 기능에 대한 모든 권한에 대해 ACL에서 테스트 클라이언트의 애플리케이션 ID를 확인합니다. 이 종류의 ACL을 사용하는 경우 호출자의 appid 값 뿐만 아니라 iss 토큰의 값을 신뢰할 수 있는지도 유효성을 검사해야 합니다.

이 종류의 권한 부여는 개인 Microsoft 계정을 가진 소비자 사용자가 소유한 데이터에 액세스해야 하는 디먼 및 서비스 계정에 일반적입니다. 조직에서 소유한 데이터의 경우 애플리케이션 사용 권한을 통해 필요한 권한 부여를 획득하는 것이 좋습니다.

roles 클레임 없이 토큰 제어

ACL 기반 권한 부여 패턴을 사용하도록 설정하기 위해 Azure AD에는 애플리케이션에 다른 애플리케이션에 대한 토큰을 가져올 수 있는 권한이 필요하지 않습니다. 따라서 roles 클레임 없이 앱 전용 토큰을 발급할 수 있습니다. API를 노출하는 애플리케이션은 토큰을 허용하기 위해 권한 확인을 구현해야 합니다.

애플리케이션에서 애플리케이션에 대한 역할 없는 앱 전용 액세스 토큰을 가져오지 못하게 하려면 앱에 대한 사용자 할당 요구 사항을 사용하도록 설정해야 합니다. 이렇게 하면 할당된 역할이 없는 사용자와 애플리케이션에서 해당 애플리케이션에 대한 토큰을 가져올 수 없게 됩니다.

애플리케이션 사용 권한

ACL을 사용하는 대신 API를 사용하여 애플리케이션 권한 세트를 노출할 수 있습니다. 애플리케이션 사용 권한은 조직의 관리자가 애플리케이션에 부여하며 해당 조직 및 그 직원이 소유한 데이터 액세스에만 사용할 수 있습니다. 예를 들어 Microsoft Graph는 다음을 수행할 수 있는 몇 가지 애플리케이션 사용 권한을 노출합니다.

  • 모든 사서함에서 메일 읽기
  • 모든 사서함에서 메일 읽기 및 쓰기
  • 모든 사용자로 메일 보내기
  • 디렉터리 데이터 읽기

Microsoft Graph가 아닌 사용자 고유의 API를 사용하여 애플리케이션 사용 권한을 사용하려면 먼저 Azure Portal의 API 앱 등록에서 범위를 정의하여 API를 노출해야 합니다. 그런 다음 클라이언트 애플리케이션의 앱 등록에서 해당 권한을 선택하여 API에 대한 액세스를 구성합니다. API의 앱 등록에서 범위를 노출하지 않은 경우 Azure Portal의 클라이언트 애플리케이션의 앱 등록에서 해당 API에 대한 애플리케이션 권한을 지정할 수 없습니다.

사용자가 아닌 애플리케이션으로 인증하는 경우 사용자가 부여하는 위임된 권한 - 범위를 사용할 수 없습니다. 관리자가 애플리케이션에 부여하거나 웹 API의 사전 인증을 통해 부여한 애플리케이션 사용 권한(역할이라고도 함)을 사용해야 합니다.

애플리케이션 권한에 대한 자세한 내용은 권한 및 동의를 참조하세요.

일반적으로 애플리케이션 사용 권한을 사용하는 애플리케이션을 빌드할 때 앱에는 관리자가 앱의 사용 권한을 승인할 수 있는 페이지 또는 보기가 필요합니다. 이 페이지는 앱 로그인 흐름의 일부, 앱 설정의 일부 또는 전용 "연결" 흐름일 수 있습니다. 대부분의 경우에 사용자가 회사 또는 학교 Microsoft 계정으로 로그인한 후에 앱은 이 "연결" 보기만을 표시하게 됩니다.

사용자가 앱에 로그인하면 사용자에게 애플리케이션 사용 권한을 승인하도록 요청하기 전에 사용자가 속해 있는 조직을 식별할 수 있습니다. 반드시 필요하지는 않지만 사용자를 위한 보다 직관적인 환경을 만드는 것이 유용할 수 있습니다. 사용자가 로그인하도록 하려면 Microsoft ID 플랫폼 프로토콜 자습서를 따르세요.

디렉터리 관리에서 사용 권한 요청

조직 관리자의 사용 권한을 요청할 준비가 되면 Microsoft ID 플랫폼 관리자 동의 엔드포인트 로 사용자를 리디렉션할 수 있습니다.

// Line breaks are for legibility only.

GET https://login.microsoftonline.com/{tenant}/adminconsent?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions

PRO 팁: 브라우저에서 다음 요청 붙여넣기를 시도합니다.

https://login.microsoftonline.com/common/adminconsent?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&state=12345&redirect_uri=http://localhost/myapp/permissions
매개 변수 조건 Description
tenant 필수 사용 권한을 요청하려는 디렉터리 테넌트입니다. 이는 GUID 또는 친숙한 이름 형식일 수 있습니다. 사용자가 속한 테넌트가 무엇인지 모르고 테넌트를 사용하여 로그인하지 않으려는 경우 common을 사용합니다.
client_id 필수 Azure Portal - 앱 등록 환경이 앱에 할당한 애플리케이션(클라이언트) ID 입니다.
redirect_uri 필수 리디렉션 URI는 처리할 앱에 응답을 전송하려는 위치입니다. URL로 인코딩되어야 한다는 점을 제외하고 포털에서 등록한 리디렉션 URI 중 하나와 정확히 일치해야 하며 추가 경로 세그먼트가 있을 수 있습니다.
state 권장 토큰 응답에도 반환되는 요청에 포함된 값입니다. 원하는 모든 콘텐츠의 문자열일 수 있습니다. 상태는 인증 요청이 발생하기 전에 앱에서 사용자 상태에 대한 정보(예: 사용한 페이지 또는 보기)를 인코딩하는 데 사용됩니다.

해당 시점에 Azure AD는 테넌트 관리자만이 요청을 완료하기 위해 로그인할 수 있도록 합니다. 관리자에게는 앱 등록 포털에서 앱에 요청한 애플리케이션 직접 사용 권한을 모두 승인하라는 메시지가 표시됩니다.

성공적인 응답

관리자가 애플리케이션에 대한 사용 권한을 승인하는 경우 성공적인 응답은 다음과 같습니다.

GET http://localhost/myapp/permissions?tenant=a8990e1f-ff32-408a-9f8e-78d3b9139b95&state=state=12345&admin_consent=True
매개 변수 Description
tenant 디렉터리 테넌트는 GUID 형식으로 요청한 권한을 애플리케이션에 부여합니다.
state 토큰 응답에도 반환되는 요청에 포함된 값입니다. 원하는 모든 콘텐츠의 문자열일 수 있습니다. 상태는 인증 요청이 발생하기 전에 앱에서 사용자 상태에 대한 정보(예: 사용한 페이지 또는 보기)를 인코딩하는 데 사용됩니다.
admin_consent True 로 설정합니다.
오류 응답

관리자가 애플리케이션에 대한 사용 권한을 승인하지 않는 경우 실패한 응답은 다음과 같습니다.

GET http://localhost/myapp/permissions?error=permission_denied&error_description=The+admin+canceled+the+request
매개 변수 Description
error 오류 유형을 분류하는 데 사용할 수 있고 오류에 대응하는 데 사용할 수 있는 오류 코드 문자열입니다.
error_description 오류의 근본 원인을 식별하도록 도울 수 있는 특정 오류 메시지입니다.

앱 프로비전 엔드포인트에서 성공적인 응답을 받았다면 앱은 요청한 애플리케이션 직접 사용 권한을 얻게 됩니다. 이제 원하는 리소스에 대한 토큰을 요청할 수 있습니다.

토큰 가져오기

애플리케이션에 필요한 권한을 부여받은 후에는 API에 대한 액세스 토큰을 획득하는 과정을 진행합니다. 클라이언트 자격 증명 권한 부여를 사용하여 토큰을 가져오려면 POST 요청을 /token Microsoft ID 플랫폼에 보내세요.

첫 번째 사례: 공유 비밀을 사용하여 액세스 토큰 요청

POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=sampleCredentia1s
&grant_type=client_credentials
# Replace {tenant} with your tenant!
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'client_id=535fb089-9ff3-47b6-9bfb-4f1264799865&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=qWgdYAmab0YSkuL1qKv5bPX&grant_type=client_credentials' 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token'
매개 변수 조건 Description
tenant 필수 애플리케이션에서 GUID 또는 도메인 이름 형식으로 작동하도록 계획하는 디렉터리 테넌트입니다.
client_id 필수 앱에 할당되는 애플리케이션 ID입니다. 앱을 등록한 포털에서 이 정보를 찾을 수 있습니다.
scope 필수 이 요청에서 scope 매개 변수에 전달된 값은 원하는 리소스의 리소스 식별자(애플리케이션 ID URI)여야 하고, .default 접미사가 붙어 있어야 합니다. Microsoft Graph 예제의 경우 값은 https://graph.microsoft.com/.default입니다.
해당 값은 앱에 구성한 모든 애플리케이션 직접 사용 권한의 Microsoft ID 플랫폼을 알려주며, 엔드포인트는 사용하려는 리소스와 연결된 사용 권한의 토큰을 발급해야 합니다. /.default 범위에 대해 자세히 알아보려면 동의 설명서를 참조하세요.
client_secret 필수 앱 등록 포털에서 앱에 대해 생성한 클라이언트 암호입니다. 클라이언트 암호는 보내기 전에 URL로 인코딩해야 합니다. 대신 RFC 6749에 따라 권한 부여 헤더에 자격 증명을 제공하는 기본 인증 패턴도 지원됩니다.
grant_type 필수 client_credentials로 설정해야 합니다.

두 번째 사례: 인증서를 사용하여 액세스 토큰 요청

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_id=97e0a5b7-d745-40b6-94fe-5f77d35c6e05
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsIng1dCI6Imd4OHRHeXN5amNScUtqRlBuZDdSRnd2d1pJMCJ9.eyJ{a lot of characters here}M8U3bSUKKJDEg
&grant_type=client_credentials
매개 변수 조건 Description
tenant 필수 애플리케이션에서 GUID 또는 도메인 이름 형식으로 작동하도록 계획하는 디렉터리 테넌트입니다.
client_id 필수 앱에 할당되는 애플리케이션(클라이언트) ID입니다.
scope 필수 이 요청에서 scope 매개 변수에 전달된 값은 원하는 리소스의 리소스 식별자(애플리케이션 ID URI)여야 하고, .default 접미사가 붙어 있어야 합니다. Microsoft Graph 예제의 경우 값은 https://graph.microsoft.com/.default입니다.
이 값은 앱에 구성한 모든 애플리케이션 직접 사용 권한의 Microsoft ID 플랫폼을 알려주며, 사용하려는 리소스와 연결된 사용 권한의 토큰을 발급해야 합니다. /.default 범위에 대해 자세히 알아보려면 동의 설명서를 참조하세요.
client_assertion_type 필수 값은 urn:ietf:params:oauth:client-assertion-type:jwt-bearer로 설정해야 합니다.
client_assertion 필수 애플리케이션의 자격 증명으로 등록한 인증서를 사용하여 만들고 서명해야 하는 어설션(JSON Web Token)입니다. 인증서 등록 방법 및 어설션 형식에 대한 자세한 내용은 인증서 자격 증명을 참조하세요.
grant_type 필수 client_credentials로 설정해야 합니다.

인증서 기반 요청에 대한 매개 변수는 공유 비밀 기반 요청과 한 가지 면에서 다릅니다. client_secret 매개 변수는 client_assertion_typeclient_assertion 매개 변수로 대체됩니다.

성공적인 응답

두 방법 중 하나의 성공적인 응답은 다음과 같습니다.

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}
매개 변수 Description
access_token 요청된 액세스 토큰입니다. 앱은 이 토큰을 사용하여 웹 API와 같은 보안 리소스를 인증할 수 있습니다.
token_type 토큰 유형 값을 나타냅니다. Microsoft ID 플랫폼이 유일하게 지원하는 형식은 bearer입니다.
expires_in 액세스 토큰이 유효한 시간(초)입니다.

경고

코드에서 이 예제의 토큰을 포함하여 소유하지 않은 API에 대한 토큰을 확인하거나 읽으려고 시도하지 마세요. Microsoft 서비스 토큰은 JWT로 유효성을 검사하지 않는 특수 형식을 사용할 수 있으며 소비자(Microsoft 계정) 사용자에 대해 암호화될 수도 있습니다. 토큰 읽기는 유용한 디버깅 및 학습 도구이지만 코드에서 이에 대한 종속성을 취하거나 제어하는 API용이 아닌 토큰에 대한 세부 사항을 가정하지 마세요.

오류 응답

오류 응답은 다음과 같습니다.

{
  "error": "invalid_scope",
  "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. The scope https://foo.microsoft.com/.default is not valid.\r\nTrace ID: 255d1aef-8c98-452f-ac51-23d051240864\r\nCorrelation ID: fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7\r\nTimestamp: 2016-01-09 02:02:12Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2016-01-09 02:02:12Z",
  "trace_id": "255d1aef-8c98-452f-ac51-23d051240864",
  "correlation_id": "fb3d2015-bc17-4bb9-bb85-30c5cf1aaaa7"
}
매개 변수 Description
error 발생한 오류 유형을 분류하고 오류에 대응하는 데 사용할 수 있는 오류 코드 문자열입니다.
error_description 인증 오류의 근본 원인을 식별하도록 도울 수 있는 특정 오류 메시지입니다.
error_codes 진단에 도움이 될 수 있는 STS 특정 오류 코드의 목록입니다.
timestamp 오류가 발생한 시간입니다.
trace_id 진단에 도움이 되는 요청에 대한 고유 식별자입니다.
correlation_id 전체 구성 요소에서 진단에 도움이 되는 요청에 대한 고유 식별자입니다.

토큰 사용

이제 토큰을 획득했으므로 토큰을 사용하여 리소스에 대한 요청을 수행합니다. 토큰이 만료되면 /token 엔드포인트에 대한 요청을 반복하여 새 액세스 토큰을 획득합니다.

GET /v1.0/me/messages
Host: https://graph.microsoft.com
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
# Pro tip: Try the following command! (Replace the token with your own.)

curl -X GET -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbG...." 'https://graph.microsoft.com/v1.0/me/messages'

코드 샘플 및 기타 설명서

Microsoft 인증 라이브러리에서 클라이언트 자격 증명 개요 설명서를 읽어보세요.

샘플 플랫폼 Description
active-directory-dotnetcore-daemon-v2 .NET Core 2.1 콘솔 사용자를 대신하지 않고 애플리케이션의 ID를 사용하여 Microsoft Graph를 쿼리하는 테넌트의 사용자를 표시하는 간단한 .NET Core 애플리케이션입니다. 샘플에는 인증에 인증서를 사용하는 다양한 사례도 설명되어 있습니다.
active-directory-dotnet-daemon-v2 ASP.NET MVC 사용자를 대신하지 않고 애플리케이션의 ID를 사용하여 Microsoft Graph에서 데이터를 동기화하는 웹 애플리케이션입니다.